WPF DataBinding监视抛出的exception

在我的模型中,我有很多不同对象的属性,我在设置对象的值时检查值,如果值不被接受,我将抛出一个exception,这与Windows窗体属性网格完美配合,但现在我正在尝试使用WPF设计新界面。 在WPF中,当我将属性绑定到像文本框这样的控件时,当值更改时,我不知道如何处理exception并显示错误消息。 例子:

public string ConnectionString { get { return (_ConnectionString); } set { try { _ConnectionString = value ; _SqlConnection = new System.Data.SqlClient.SqlConnection(_ConnectionString); _ConnectionTested = true; } catch (Exception caught) { _ConnectionTested = false; _TableNameTested = false; _FieldNameTested = false; _ConditionTested = false; _ConnectionString = ""; //----delete values---- ValuesCollection.Clear(); throw (new Exception("Can not Open the connection String \nReason : " + caught.Message )); } } } 

和wpf部分是这样的:

  

无论如何,当文本框中的值更改时,检查模型是否抛出exception,然后向用户显示exception.message?

谢谢

看一下绑定validation 。 Binding类有一个ValidationRules集合,您可以在其中添加ExceptionValidationRule

肯特对使用ValidationRule和ExceptionValidationRule完全正确。 但是,你会发现这个解决方案非常不愉快,因为你有很多绑定到这样的字段的情况。 在许多地方你将取代这样的东西:

  

有了这个:

          

因为这是如此笨拙,我喜欢创建一个自动应用validation规则的inheritance附加属性,所以我要说的是:

   

我的附加属性会自动对窗口中的每个绑定应用validation,因此各个文本框不必担心validation。

要做到这一点,我使用这个一般技术:

  public class ValidationHelper : DependencyObject { [ThreadStatic] static List _objectsNeedingValidationUpdate; public static ControlTemplate GetErrorTemplate(DependencyObject obj) { return (ControlTemplate)obj.GetValue(ErrorTemplateProperty); } public static void SetErrorTemplate(DependencyObject obj, ControlTemplate value) { obj.SetValue(ErrorTemplateProperty, value); } public static readonly DependencyProperty ErrorTemplateProperty = DependencyProperty.RegisterAttached("ErrorTemplate", typeof(ControlTemplate), typeof(ValidationHelper), new FrameworkPropertyMetadata { Inherits = true, PropertyChangedCallback = (obj, e) => { if(e.NewValue) if(_objectsNeedingValidationUpdate!=null) _objectsNeedingValidationUpdate.Add(obj); else { _objectsNeedingValidationUpdate = new List(); _objectsNeedingValidationUpdate.Add(obj); Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new Action(UpdateValidations)); } }, }); static void UpdateValidations() { List objects = _objectsNeedingValidationUpdate; _objectsNeedingValidationUpdate = null; if(objects!=null) foreach(DependencyObject obj in objects) UpdateValidations(obj); } static void UpdateValidations(DependencyObject obj) { // My regular code uses obj.GetLocalValueEnumerator here, but that would require some other complexity if(UpdateValidations(obj, TextBox.TextProperty)) if(Validation.GetErrorTemplate(obj)==null) Validation.SetErrorTemplate(obj, ValidationHelper.GetErrorTemplate(obj)); } static bool UpdateValidations(DependencyObject obj, DependencyProperty prop) { var binding = BindingOperations.GetBinding(obj, prop); if(binding!=null && binding.Mode==BindingMode.TwoWay && !binding.ValidationRules.Any(rule => rule is ExceptionValidationRule)) { binding.ValidationRules.Add(new ExceptionValidationRule()); BindingOperations.SetBinding(obj, prop, binding); // Required to get new rule to work return true; } return false; } } 

有关如何创建errorTemplate资源的示例,请参阅Validation类的MSDN文档。 另请注意:

  • 我的ValidationHelper类不会阻止您在单个TextBox上设置自定义Validation.ErrorTemplate值。 这些将覆盖ValidationHelper.ErrorTemplate。
  • 您可以轻松添加对TextBox以外的控件和Text以外的属性的支持