[英]Create Blazor custom date picker component with nullable and non-nullable date value
I want to create custom date picker component in Blazor. My code is like that我想在 Blazor 中创建自定义日期选择器组件。我的代码就是这样
<div class="form-group">
<label>@Title</label>
<input type="date" class="form-control" @bind="Value" />
</div>
@code{
[Parameter]
public string Title { get;set; }
private DateTime? _value;
[Parameter]
public DateTime? Value
{
get
{
return _value;
}
set
{
if (Value == _value)
{
return;
}
_value = value;
ValueChanged.InvokeAsync(value);
}
}
[Parameter]
public EventCallback<DateTime?> ValueChanged { get; set; }
}
the problem is that component only works if the value is nullable DateTime (DateTime?), and if value is DateTime it throws error问题是该组件仅在值为可为空的 DateTime(DateTime?)时才有效,如果值为 DateTime,则会抛出错误
cannot convert from 'Microsoft.AspNetCore.Components.EventCallback<System.DateTime>' to 'Microsoft.AspNetCore.Components.EventCallback'
I decided to make the bind value accepts nullable because I thought it will accept both types.我决定让绑定值接受可为空,因为我认为它会接受这两种类型。 It works like that with int, double...etc.
它像 int、double...等一样工作。 So I want to make it accept DateTime and DateTime?
所以我想让它接受 DateTime 和 DateTime? Any ideas to make it?
有什么想法吗?
Update : I tried to make the component accepts generic type but it throws error Cannot convert T to DateTime更新:我试图让组件接受通用类型,但它抛出错误Cannot convert T to DateTime
Here your component with generics:这是您的组件 generics:
@using System.Globalization
@using System
@typeparam TValue
<div class="form-group">
<label>@Title</label>
<input
type="date"
class="form-control"
value="@FormatValueAsString(Value)"
@onchange="@OnChange"
/>
</div>
@code {
private const string DateFormat = "yyyy-MM-dd";
CultureInfo provider = CultureInfo.InvariantCulture;
private TValue _value;
[Parameter] public string Title {get; set;}
[Parameter] public TValue Value
{
get
{
return _value;
}
set
{
if (EqualityComparer<TValue>.Default.Equals(value , _value))
{
return;
}
_value = value;
ValueChanged.InvokeAsync(value);
}
}
[Parameter] public EventCallback<TValue> ValueChanged { get; set; }
private void OnChange( ChangeEventArgs args)
{
try
{
Value =
(TValue)(object)
DateTime
.ParseExact(args.Value.ToString(),DateFormat, provider);
}
catch {
Value = default(TValue); // not sure you want this
}
}
protected string FormatValueAsString(TValue? value)
{
switch (value)
{
case DateTime dateTimeValue:
var r = BindConverter.FormatValue(dateTimeValue, DateFormat, provider);
return r;
default:
return string.Empty;
}
}
}
But... I suggest to you to inherit from InputDate .但是......我建议你继承InputDate 。
Take a look to "Option 2 (recomended): Through inheritance from InputBase "查看“选项 2(推荐):通过 InputBase 的 inheritance”
To check i out at https://blazorrepl.com/repl/QlYPQBFj03U9ITNe13要检查我在https://blazorrepl.com/repl/QlYPQBFj03U9ITNe13
Much simpler way would be to inherit form Microsoft's InputDate component.更简单的方法是继承 Microsoft 的 InputDate 组件。 I have done the same to implement Bootstrap4 validation styling in Blazor, see the following snippets:
我在 Blazor 中做了同样的事情来实现 Bootstrap4 验证样式,请参阅以下代码片段:
@inherits InputDate<TValue>
@typeparam TValue
<input @attributes="AdditionalAttributes"
type="date"
class="@Bs4InputHelpers.FixClassNames(CssClass)"
value="@BindConverter.FormatValue(CurrentValueAsString)"
@oninput="EventCallback.Factory.CreateBinder<string>(
this, value => CurrentValueAsString = value, CurrentValueAsString)" />
@code {
}
And for the Helper:对于助手:
public static class Bs4InputHelpers
{
public static string FixClassNames(string inputClassNames)
{
//NOTE: Notice the space in front of the class name, this is to ensure we get
// the suffix to our existing form-control class set from the mark up and NOT
// half of an invalid tag. We could use a reg-ex but that might be a bit
// too slow for the UI rendering to stay smooth.
// The invalid string shall always be fixed up, as we can never get it until the
// element has checked at least once by an attempted submit.
string result = inputClassNames.Replace(" invalid", " is-invalid");
// The valid tag is on by default, and to keep consistency with BS4 we only want
// it to appear either when our field is modified, or we've tried a submit
if (inputClassNames.Contains("modified"))
{
result = result.Replace(" valid", " is-valid");
}
return result;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.