Reputation: 543
I´m trying to use MudBlazor DatePicker in my web application.
When I´m using it with @bind-Date
the way it´s described in the documentation
Note: Always use the two-way binding @bind-Date to bind to a field of type DateTime?
like this...
<MudDatePicker
Editable="true"
@bind-Date="@InternalDate"
Clearable=true
DateFormat="@CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern"
Mask="@(new DateMask(CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern))" />
it works as I expect it to.
Except this way I can´t invoke anything when InternalDate
changes...the way I´ve set up my form fields is that I actually need to invoke my own EventCallBack<DateTime?>, which will then be used by the encapsulation component to set property values through reflection and trigger stuff like validating the model.
With all other MudBlazor entry field components I could simply pass down some Value
and ValueChanged
properties and everything worked, but if I try that with DatePicker like this...
<MudDatePicker
Editable="true"
Date="@InternalDate"
DateChanged="InternalDateChanged"
Clearable=true
DateFormat="@CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern"
Mask="@(new DateMask(CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern))" />
I get weird behavior. It then only works when picking with the calendar. Editing the date directly in text causes InternalDateChanged to be invoked twice. Once with the correct value, once with the old previous value.
The behavior is the same if I try to invoke from the setter. The setter gets called twice.
private DateTime? InternalDate
{
get => Value;
set {
Value = value;
ValueChanged.InvokeAsync(value);
}
}
It stops doing the second unwanted invokation if I remove the DateFormat and Mask...but that's not really a solution...
Is there anything else I can do to have this component work and still get some kind of notification when InternalDate
changes?
Upvotes: 1
Views: 3336
Reputation: 30036
As a starting point to identify your problem here are several implementations of the MudDatePicker with different ways of setting values and driving events that I used to try and produce a "minimum reproducable example" of your issue.
They all work as I expect them to. What am I missing? Can you use this code to reproduce your issue?
@page "/"
@using System.Globalization
<PageTitle>Index</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">Date Test</MudText>
<div class="m-2">
<MudDatePicker Editable="true"
@bind-Date="@date1"
Clearable=true
DateFormat="@CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern"
Mask="@(new DateMask(CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern))" />
<MudDatePicker Editable="true"
Date=@date2
DateChanged=@OnDateChanged
Clearable=true
DateFormat="@CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern"
Mask="@(new DateMask(CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern))" />
<MudDatePicker Editable="true"
@bind-Date="@date3"
Clearable=true
DateFormat="@CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern"
Mask="@(new DateMask(CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern))" />
</div>
<MudAlert Severity="Severity.Normal" class="mt-4">
Date1 :@date1
</MudAlert>
<MudAlert Severity="Severity.Info" class="mt-4">
Date2: @date2
</MudAlert>
<MudAlert Severity="Severity.Warning" class="mt-4">
Date3: @date3
</MudAlert>
<MudAlert Severity="Severity.Success" class="mt-4">
@message
</MudAlert>
@code {
DateTime? date1 = DateTime.Today;
DateTime? date2 = DateTime.Today;
DateTime? _date3 = DateTime.Today;
DateTime? date3 {
get => _date3;
set {
if (!_date3.Equals(value))
{
_date3 = value;
ValueChanged?.Invoke(value);
}
}
}
private Action<DateTime?>? ValueChanged;
private string message = $"Not Set";
public Index()
=> ValueChanged = this.SetValue;
private Task OnDateChanged(DateTime? value)
{
date2 = value;
message = $"Current date set to {date2?.ToString("dd-MMM-yyyy")}";
// Do something Async
return Task.Delay(10);
}
private void SetValue(DateTime? value)
=> message = $"Current date set to {value?.ToString("dd-MMM-yyyy")}";
}
Upvotes: 1