Radzen: Bind RadzenDatePicker value to TimeOnly property

2.3k Views Asked by At

I am using the RadzenDatePicker to get time value only. I have managed to make it show only time instead of the calendar, however, I can't bind it's value which is DateTime to TimeOnly.

Is there a way I can bind the RadzenDatePicker below to TimeOnly property?

Code:

<RadzenDatePicker style="display: block; width: 100%" 
                  @bind-Value="@station.OpenTime" 
                  Name="OpenTime" 
                  TValue="TimeOnly" 
                  ShowTime="true" 
                  HourFormat="12"
                  TimeOnly="true"/>

Control:

Radzen DatePicker to TimeSpan

Error:

System.InvalidCastException: Unable to cast object of type 'System.DateTime' to type 'System.TimeOnly'.
         at Radzen.Blazor.RadzenDatePicker`1.OnChange()
         at Radzen.Blazor.RadzenDatePicker`1.OkClick()
         at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

2

There are 2 best solutions below

0
On BEST ANSWER

Blazor databinding is type-safe so this won't work directly. The TValue parameter is a bit of a lie. It will only accept DateTime and maybe DateTimeOffset.

So you will need a DateTime value to bind to and then you can update your target with the Change event:

<RadzenDatePicker style="display: block; width: 100%" 
                  @bind-Value="@openDateTime" 
                  Change="UpdateOpenTime"
                  Name="OpenTime" 
                @*TValue="TimeOnly"*@ 
                  ShowTime="true" 
                  HourFormat="12"
                  TimeOnly="true"/>
DateTime openDateTime; // initialize somewhere

void UpdateOpenTime(DateTime? dateTime)
{
   if (dateTime is null) return;
   station.OpenTime = TimeOnly.FromDateTime(dateTime.Value);
}

When you need this a lot you could wrap the Radzen component with one of your own.

0
On

I got an idea from Henk answer and went ahead and created my component to help me bind TimeOnly property to a RadzenDatePicker control.

RadzenTimePicker.razor

@using Radzen.Blazor
<RadzenDatePicker style="display: block; width: 100%"
                  @bind-Value="@dateTime"
                  TValue="DateTime?"
                  Change="UpdateTime"
                  Name="@Name"
                  DateFormat="hh:mm tt" 
                  ShowTime="true"
                  HourFormat="12"
                  TimeOnly="true"/>

@code {
    [Parameter]
    public TimeOnly TimeValue { get; set; }

    [Parameter]
    public EventCallback<TimeOnly> TimeValueChanged { get; set; }
    
    [Parameter]
    public string Name { get; set; }

    private DateTime? dateTime { get; set; }

    protected override void OnInitialized()
    {
        dateTime = (new DateTime()).Add(TimeValue.ToTimeSpan());
        base.OnInitialized();
    }

    void UpdateTime(DateTime? dateTime)
    {
        if (dateTime is null) return;
        TimeValue = TimeOnly.FromDateTime(dateTime.Value); ;
        TimeValueChanged.InvokeAsync(TimeValue);
    }
}

Usage:

<RadzenTimePicker @bind-TimeValue="@station.OpenTime" Name="OpenTime" />

Result:

RadzenDatePicker binding with TimeOnly property