I wanted to create a custom TimePickerComponent
and use it everywhere in my app where i use a MudTimePicker
. This, because that way I can easily configure AutoClose=false
everywhere, and in the future maybe also other custom options.
The previous snippet is solved by the comments below. However, it seems that the surrounding components have influence on it as well. The TimePickerComponent
is inside a MudDataGrid
.
<MudDataGrid T=Item Items="_items"
Striped=true Hover=true Dense="true" Square="true" Elevation="0" Bordered="true"
ReadOnly="false"
EditMode="DataGridEditMode.Form"
EditTrigger="DataGridEditTrigger.Manual"
StartedEditingItem="StartedEditingItem"
CommittedItemChanges="CommittedItemChanges">
<Columns>
<PropertyColumn Property="item => item.DeleteDate" Title="Delete Date" Sortable="true" Filterable="true">
<EditTemplate>
<MudDatePicker @bind-Date="@deletedDate" Label="Delete Date" />
<MudTimePicker @bind-Time="@deletedTime" Label="Delete Date" />
<TimePickerComponent @bind-TimeValue="@deletedTime" Label="Delete Time From Custom Component" />
</EditTemplate>
</PropertyColumn>
<TemplateColumn>
<CellTemplate>
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Edit" OnClick="@context.Actions.StartEditingItemAsync" />
</CellTemplate>
</TemplateColumn>
</Columns>
</MudDataGrid>
I am now using the new TimePickerComponent as provided by @RBee .
<MudTimePicker @ref=_picker Time=@TimeValue TimeChanged="HandleTimeChange" Label=@Label AutoClose="false">
<PickerActions>
<MudButton OnClick="@(() => _picker.CloseAsync(false))">Cancel</MudButton>
<MudButton Color="Color.Primary" OnClick="@(() => _picker.CloseAsync())">Ok</MudButton>
</PickerActions>
</MudTimePicker>
@code {
[Parameter]
public TimeSpan? TimeValue { get; set; }
[Parameter]
public EventCallback<TimeSpan?> TimeValueChanged { get; set; }
[Parameter]
public string Label { get; set; }
public MudTimePicker _picker;
public async void HandleTimeChange(TimeSpan? newTime){
await TimeValueChanged.InvokeAsync(newTime);
}
}
The HandleTimeChange
gets called twice, once with the correct value, and once with the value null. This means, that it still does not work unfortunately. See this snippet: try.mudblazor.com/snippet/cuwoaCaKTmCeSBDO
Original post/code:
<MudDatePicker @bind-Date="@deletedDate" Label="Delete Date" />
<MudTimePicker @bind-Time="@deletedTime" Label="Delete Time"/>
<TimePickerComponent @bind-TimeValue="@deletedTime" Label="Delete Time From Custom Component"/>
@code{
public DateTime? deletedDate { get; set; }
public TimeSpan? deletedTime { get; set; }
}
However, the parent component seems to be unable to show the time I've picked in my TimePickerComponent
component. I created a MudBlazor snippet here: https://try.mudblazor.com/snippet/cYmIuiYpzoGHegIi . When I use the MudTimePicker
to pick a time, both the MudTimePicker
and the TimePickerComponent
show the selected time. Not vice versa.
I have tried MudBlazor 7.4 and 7.5 packages, they both show the same behavior.
I expect something is wrong with the way I have configured the TimeValueChanged EventCallBack
.
I have also tried defining an OnOkButtonClicked
function where I invoke the TimeValueChanged
async. However, this also does not seem to be working.
private void OnOkButtonClicked()
{
TimeValueChanged.InvokeAsync();
_picker.CloseAsync();
}
You have to use the EventCallback to notify the parent of a change.
Directly @bind
'ing across multiple components is not a good idea.
In the example below, we use Time
and TimeChanged
instead of @bind-Time
, Then in the handler method HandleTimeChange
we don't assign the new value to TimeValue
as that is the parent components responsibility, we only invoke the TimeValueChanged
EventCallback
thereby notifying the parent of a change.
<MudTimePicker @ref=_picker Time=@TimeValue TimeChanged="HandleTimeChange" Label=@Label AutoClose="false">
<PickerActions>
<MudButton OnClick="@(() => _picker.CloseAsync(false))">Cancel</MudButton>
<MudButton Color="Color.Primary" OnClick="@(() => _picker.CloseAsync())">Ok</MudButton>
</PickerActions>
</MudTimePicker>
@code {
[Parameter]
public TimeSpan? TimeValue { get; set; }
[Parameter]
public EventCallback<TimeSpan?> TimeValueChanged { get; set; }
[Parameter]
public string Label { get; set; }
public MudTimePicker _picker;
public void Dispose()
{
_picker.DisposeAsync();
}
private async void HandleTimeChange(TimeSpan? newTime){
await TimeValueChanged.InvokeAsync(newTime);
}
}
Edit: Updated to the code change in question.
Seems you also need to assign the Time value in the custom component. Not entirely sure why, although the docs does note
Note: Always use the two-way binding @bind-Time to bind to a field of type TimeSpan?
[Parameter]
public TimeSpan? TimeValue { get; set; }
[Parameter]
public EventCallback<TimeSpan?> TimeValueChanged { get; set; }
private async void HandleTimeChange(TimeSpan? newTime){
TimeValue=newTime; // also assigned here
await TimeValueChanged.InvokeAsync(newTime);
}