【问题标题】:S/L 4 & IDataErrorInfo - How to force re-validation of a control (when a related control is touched)S/L 4 & IDataErrorInfo - 如何强制重新验证控件(触摸相关控件时)
【发布时间】:2011-01-13 23:54:30
【问题描述】:

我有两个控件绑定到属性 MinCartValue 和 MaxCartValue。 MinCartValue 必须小于 MaxCartValue。为了实现这个验证,我实现了 IDataErrorInfo 接口,如果 MinCartValue 或 MaxCartValue 被触及,则在 this[columnName] 方法中运行上述检查。 ValidatesOnDataErrors=True 在两个控件的绑定中设置。 验证正常工作,当对其属性值的更改违反规则时突出显示每个控件。问题是一旦一个控件被标记为无效,如果用户通过更改另一个控件的值来纠正问题,第一个控件仍然被标记为无效。这是可以理解的,因为 IDataErrorInfo 方法没有对第一个控件的属性进行验证。

所以我需要一种在属性 #2 被验证时强制属性 #1 被重新验证的方法(或清除无效状态的方法),反之亦然。我曾尝试在我的 this[columnName] 方法中调用 RaisePropertyChanged,但它什么也没做。还尝试将属性设置为自己的值以试图欺骗它来验证自己,但还是没有任何反应。

谢谢

【问题讨论】:

    标签: silverlight validation idataerrorinfo


    【解决方案1】:

    我建议查看INotifyDataErrorInfo 界面(在 Silverlight 4 中引入)。如果属性变得无效,它能够异步通知,所以我认为框架更好地在许多属性中尊重这一点,而不是期望当前正在更改的属性是唯一其有效性可能正在更改的属性。

    【讨论】:

    • 为什么INotifyDataErrorInfo不在WPF中?好用的界面!
    【解决方案2】:

    我有两个需要相互验证的 DateTime 属性(DateFrom 和 DateTo)。在这些属性的设置器中,我刚刚为 DateTo 和 DateFrom 引发了一个 PropertyChanged 事件。像魅力一样工作。

    【讨论】:

      【解决方案3】:

      我不确定我是否完全理解您的问题,但也许这可能会有所帮助。提供一些示例 XAML 和绑定属性代码会有所帮助。

      这听起来像是您的代码的问题,具体取决于默认的 UpdateSourceTrigger,在 TextBox 控件的情况下是它们的焦点/不焦点。您可以在 XAML 中设置 UpdateSourceTrigger 属性,方法是将 UpdateSourceTrigger=Explicit 添加到发生验证的绑定中。然后在每个TextBox(MinCartValue, MaxCartValue)中,为TextChanged事件添加一个事件处理函数。

      在事件处理程序的代码隐藏中,您可以执行以下操作:

          private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
          {
              TheTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
          }
      

      在这种情况下,TheTextBox 将是您的购物车控件之一。 UpdateSource() 方法是一种手动更新绑定值的方法,这应该会触发您的验证。此方法提供了绑定到触发器以更新值并且提升属性已在默认范围之外发生更改(在此实例中使用更改的文本而不是焦点和取消焦点在 TextBox 上)。

      【讨论】:

      • 谢谢。我应该提到我正在使用 MVVM 方法,其中“代码背后”没有对 XAML 控件的引用。我想坚持这一点,所以我正在寻找一种方法来通过仅引用充当数据上下文的对象的属性来做到这一点。
      • 是的,我不知道您是否使用了 MVVM。我尝试自己关注 MVVM,但不幸的是,我还没有想出一个好的 MVVM 解决方案来解决这个问题。
      【解决方案4】:

      这是我解决它的方法。假设 Property1 和 Property2 是相互依赖的。我还不熟悉 MVVM,但您可能正在扩展您的实体类以实现 IDataErrorInfo。在这种情况下,您还可以扩展 On[Property]Changed 方法并报告相关属性的更改:

      partial class YourEntity : IDataErrorInfo
      {
          public string this[string columnName]
              {
                  //Your validation logic
              }
      
          public string Error
          {
              //WPF doesn't use it anyway
              get { return string.Empty; }
          }
      
          partial void OnProperty1Changed() 
          {
              OnPropertyChanging("Property2");
              OnPropertyChanged("Property2");
          }
      
          partial void OnProperty2Changed()
          {
              OnPropertyChanging("Property1");
              OnPropertyChanged("Property1");
          }
      }
      

      在这种情况下,任何一个属性的更新都会使两个绑定控件重新评估自己。

      EDIT2:看来您应该使用 OnPropertyChang* 而不是 ReportPropertyChang*。 ReportPropertyChanged 将通知实体框架模型中有待处理的更改,但实际上您要做的只是通知视图。您不想使用没有真正改变的属性来更新数据库。 ReportPropertyChang* 也将在数据库中没有映射的计算字段上失败。 EDIT1:发现必须在 ReportPropertyChanged 之前调用 ReportPropertyChanging。

      【讨论】:

      • 谢谢,但 ReportPropertyChanged 在我的项目中不可用。它是实体框架的一部分吗??
      • 是的,它是EntityObject的一个受保护的方法。起初我没有意识到你的问题是关于 Silverlight 的。我正在使用 WPF,不确定它与 SL 有何关联。
      猜你喜欢
      • 2012-11-02
      • 1970-01-01
      • 2011-02-22
      • 2011-12-09
      • 2018-03-06
      • 2015-04-21
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多