为何EditContext.OnFieldChanged事件未触发?
问题原因及解决方案
核心原因
你在<AddressForm>组件中手动创建了EditContext并订阅了OnFieldChanged事件,但输入控件DxTextBox用的是@bind-Text="@Value!.StreetNumberAndName"这种直接绑定属性的方式,不会关联到你创建的EditContext,因此该上下文的OnFieldChanged事件不会被触发。
另外,父组件已经存在一个EditForm和对应的EditContext,子组件中独立创建的EditContext会形成上下文嵌套,输入控件实际可能关联的是父组件的上下文,进一步导致子组件的OnFieldChanged无法触发。
解决方案
方案一:复用父组件的EditContext(推荐)
子组件无需自行创建EditContext,通过级联参数自动获取父组件的上下文,这样输入控件的变更会统一触发上下文事件,子组件也能正常监听:
- 修改子组件的C#代码:
[CascadingParameter] private EditContext? ParentEditContext { get; set; } private EditContext? Context { get; set; } protected override void OnInitialized() { Value ??= new AddressFormPageModel(); // 优先使用父组件的EditContext,无则创建兜底 Context = ParentEditContext ?? new EditContext(Value); Context.OnFieldChanged += OnFieldChanged; } private async void OnFieldChanged(object? sender, FieldChangedEventArgs e) { IsValidated = false; if (ValueChanged.HasDelegate) await ValueChanged.InvokeAsync(Value); }
- 在子组件的Razor代码中,用
EditForm包裹表单区域并关联Context:
<EditForm EditContext="Context"> <DxFormLayout > <DxFormLayoutItem Caption="Street Address:" Field="@nameof(Value.StreetNumberAndName)" ColSpanMd="12"> <DxTextBox @bind-Text="@Value!.StreetNumberAndName" ReadOnly="@ReadOnly" ShowValidationIcon="true" /> </DxFormLayoutItem> <!-- 其他表单项 --> </DxFormLayout> </EditForm>
方案二:手动触发字段变更通知(适合独立上下文场景)
如果必须使用子组件独立的EditContext,可以在模型属性的setter中手动通知上下文字段变更:
修改AddressFormPageModel的StreetNumberAndName属性:
private string _streetNumberAndName; public string StreetNumberAndName { get => _streetNumberAndName; set { if (_streetNumberAndName != value) { _streetNumberAndName = value; // 通知EditContext字段已变更 var fieldId = new FieldIdentifier(this, nameof(StreetNumberAndName)); Context?.NotifyFieldChanged(fieldId); } } }
注意:这种方式需要模型能访问到子组件的Context,可以通过构造函数注入或者在组件初始化模型时传递上下文。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

