wpf - 首次加载时的验证绑定(bind)

标签 wpf validation binding

我仍在为 WPF 中的验证而苦苦挣扎。

我有一个自定义验证规则,它要求文本出现在文本框中,即它强制执行强制字段约束。

<TextBox local:Masking.Mask="^[a-zA-Z0-9]*$" x:Name="CameraIdCodeTextBox" Grid.Row="1" Grid.Column="1">
  <Binding Path="CameraIdCode" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True" ValidatesOnExceptions="True">
    <Binding.ValidationRules>
      <localValidation:RequiredFieldRule />
    </Binding.ValidationRules>
  </Binding>
</TextBox>

问题是,当 Window 首次加载时,TextBox 中没有文本(如您所料)。但是 Text 属性被绑定(bind)到 ViewModel 上的属性,因此,验证规则正在触发,这表明 Window 存在问题 - 在用户甚至有机会违反业务规则之前。

这是以前解决过的问题吗?我不可能是第一个体验到这一点的人。我敢肯定,这对年轻球员来说是个陷阱。

最佳答案

这有几种模式。我通常在类/模型上实现 ISupportInitialize界面,这将需要您创建 BeginInit()EndInit()在这些方法中,我只是设置了一个私有(private) bool _isInitializing为真或假。

在 View 模型中或创建/填充模型/类的位置/时间用 begin 和 end init 包装它:

var o = new SampleObject();
o.BeginInit()
o.StartDate = DateTime.Now; //just some sample property...
o.EndInit();

因此,根据您的 ValidationRule 的调用方式,您可以检查 _isInitializing 的状态看看你是否需要验证。

最近我一直在使用在 PropertyChanged 上触发的属性验证器。所以你可以做类似的事情:
[CustomValidator("ValidateStartDate")]
 public DateTime StartDate
 { get ...
 {
   set
     {
       if(_startDate == value) return;
       _startDate = value;
       if(_isInitializing) return;
       RaisePropertyChange(() => StartDate);
      }..

如果您不想打扰 ISupportInitialize ,然后在构造过程中传递您在属性中需要的所有值,而不是属性。绑定(bind)将第一次查询您的属性上的 getter 并获取它们的值,之后任何事情都将通过属性 setter 并得到验证:
 //c-tor
 public MyObject(DateTime start)
 {
    _startDate = start;
 }

关于wpf - 首次加载时的验证绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9802290/

相关文章:

javascript - 如何使用 Yup 验证对象数组中至少一个对象键具有真实值?

c# - 在 WPF C# 中填充 ComboBox 项

wpf - 状态栏不总是更新

c# - 如果存在验证错误,也要更新 ViewModel 中的属性

wpf - 第二次尝试将内容绑定(bind)到窗口时出错

c# - 将对象列表中的 bool 属性公开给 WPF 复选框

Javascript 验证 - 检查字符串是否是正确的对象

ruby-on-rails - 仅在存在时验证属性(仅当用户填写时)

android - 如何在包含的布局和多个模型中管理数据绑定(bind)?

javascript - 当 View 字段为空时,按 View 生成 Angular 模型属性