You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MudBlazor子组件中MudDatePicker首次点击无法选中日期问题

问题描述

我将MudDatePicker封装在可复用的Payment组件中,相关代码如下:

父页面代码(Razor)

<MudText>@((MarkupString)paymentsMade)</MudText>
<div>
    <span>Add Payment</span>
    <MudIconButton Icon="fas fa-solid fa-plus"
                   aria-label="Add Payment"
                   Color="Color.Success"
                   Size="Size.Small"
                   Variant="Variant.Outlined"
                   OnClick="AddPayment">
    </MudIconButton>
</div>

@if (_newClaimModelStep1.PaymentsList.Any())
{
    foreach (var payment in _newClaimModelStep1.PaymentsList)
    {
        <Payment PaymentModel="@payment"></Payment>

        <MudIconButton Icon="fas fa-solid fa-minus"
                       aria-label="Delete Address"
                       Color="Color.Error"
                       Size="Size.Small"
                       Variant="Variant.Outlined"
                       OnClick="@(() => RemovePayment(payment))">
        </MudIconButton>
    }
}

父页面后台代码(C#)

public void AddPayment()
{
    _newClaimModelStep1.PaymentsList.Add(new PaymentInfo());
}

protected void RemovePayment(PaymentInfo payment)
{
    _newClaimModelStep1.PaymentsList.Remove(payment);
}

Payment组件标记代码(Razor)

<MudItem xs="12" Class="pb-3">
    <MudDatePicker @bind-Date="@PaymentModel.PaymentDate" Clearable
                    Editable="true"
                    DateFormat="MM/dd/yyyy"
                    IsDateDisabledFunc="@((DateTime dt) => dt > DateTime.Now.Date)"
                    Mask="@(new DateMask("MM/dd/yyyy"))"
                    Label="Payment Date"
                    Variant="Variant.Outlined"
                    Margin="MudBlazor.Margin.Dense"
                    For="@(() => PaymentModel.PaymentDate)" />
 </MudItem>

Payment组件后台代码(C#)

[Parameter]
public PaymentInfo PaymentModel { get; set; } = new();

Payment模型(C#)

[Required(ErrorMessageResourceType = typeof(WebResource), ErrorMessageResourceName = nameof(WebResource.PaymentDateRequired))]
[DataType(DataType.DateTime)]
public DateTime? PaymentDate { get; set; } // MudBlazor needs this to be Nullable

当前异常表现

点击MudDatePicker的日历图标时,首次选择日期无法同步到输入框;需先点击任意其他日期(此时该日期能正常显示),再点击目标日期才生效。直接手动输入日期则完全正常。非嵌入组件或直接将MudDatePicker放在父页面时,无此问题。

可能的原因及修复方案

1. 缺少子组件参数变更通知

Blazor默认不会自动监听引用类型参数内部属性的变化,当PaymentModel.PaymentDate修改时,子组件无法感知到变化并触发重新渲染,导致首次选择日期后UI未同步。

修复方式:
在Payment组件中使用内部变量中转日期绑定,并手动触发状态变更:

[Parameter, EditorRequired]
public PaymentInfo PaymentModel { get; set; } = new();

private DateTime? _internalDate;

protected override void OnParametersSet()
{
    base.OnParametersSet();
    _internalDate = PaymentModel.PaymentDate;
}

private void OnDateChanged(DateTime? date)
{
    _internalDate = date;
    PaymentModel.PaymentDate = date;
    StateHasChanged();
}

同时修改组件内的MudDatePicker绑定:

<MudDatePicker @bind-Date="_internalDate" 
               DateChanged="OnDateChanged"
               Clearable
               Editable="true"
               DateFormat="MM/dd/yyyy"
               IsDateDisabledFunc="@((DateTime dt) => dt > DateTime.Now.Date)"
               Mask="@(new DateMask("MM/dd/yyyy"))"
               Label="Payment Date"
               Variant="Variant.Outlined"
               Margin="MudBlazor.Margin.Dense"
               For="@(() => PaymentModel.PaymentDate)" />

2. Foreach循环未指定唯一Key

父页面使用foreach渲染Payment组件时,未给子组件指定@key,Blazor的Diff算法无法准确识别每个组件的身份,可能导致渲染逻辑异常。

修复方式:
在foreach循环中添加@key,确保每个Payment组件有唯一标识:

@foreach (var payment in _newClaimModelStep1.PaymentsList)
{
    <Payment PaymentModel="@payment" @key="@payment"></Payment>

    <!-- 移除按钮代码 -->
}

如果PaymentInfo没有天然的唯一属性,可给模型添加一个Id字段:

public class PaymentInfo
{
    public Guid Id { get; set; } = Guid.NewGuid();
    // 其他原有属性...
}

然后将@key绑定到该Id:@key="@payment.Id"

3. 双向绑定的引用类型特性问题

直接绑定到PaymentModel.PaymentDate时,由于PaymentInfo是引用类型,Blazor的变更检测机制可能无法及时捕捉到内部属性的修改,使用内部变量中转可以规避这个问题(即方案1的处理方式)。

内容的提问来源于stack exchange,提问作者JimboJones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:23:19