2011-02-08 101 views
2

有没有人知道如何在扩展器内的控件中发生IDataError验证的情况下更改扩展器样式的方法。例如。WPF扩展器验证

<Expander Header="Details"> 
    <TextBox Text="{Binding Brand.DESCRIPTION, 
          UpdateSourceTrigger=LostFocus, 
          ValidatesOnDataErrors=True}"/> 
</Expander> 

所以如果文本框有错误,我的扩展器的样式会改变(也许会变成红色)。 我正在寻找尽可能通用的,所以如果可能的话,不用绑定到扩展器内的每个控件。

+0

听起来像自定义类!自定义扩展器,自定义内部控件,内部控件触发IDataError事件,扩展器订阅这些事件,相应处理。 – FlyingStreudel 2011-02-08 18:55:27

回答

2

通过附加行为,您可以利用附加事件Validation.Error(每当发生验证错误时添加或删除)。要完成这项工作,您需要将NotifyOnValidationError=True添加到绑定。

这附加的行为,ChildValidation,订阅了Validation.Error事件如果NotifyOnValidationError设置为True上绑定这是冒泡的Expander。由于几个Control可能位于Expander之内,因此还需要跟踪当前激活的验证错误的计数,以确定是否显示红色边框。它可能看起来像这样

的XAML

<Expander Header="Details" 
      behaviors:ChildValidationBehavior.ChildValidation="True"> 
    <TextBox Text="{Binding Brand.DESCRIPTION, 
          UpdateSourceTrigger=LostFocus, 
          ValidatesOnDataErrors=True, 
          NotifyOnValidationError=True}"/> 
</Expander> 

ChildValidationBehavior

public static class ChildValidationBehavior 
{ 
    private static readonly DependencyProperty ErrorCountProperty = 
     DependencyProperty.RegisterAttached("ErrorCount", 
              typeof(int), 
              typeof(ChildValidationBehavior)); 
    private static void SetErrorCount(DependencyObject element, int value) 
    { 
     element.SetValue(ErrorCountProperty, value); 
    } 
    private static int GetErrorCount(DependencyObject element) 
    { 
     return (int)element.GetValue(ErrorCountProperty); 
    } 

    public static readonly DependencyProperty ChildValidationProperty = 
     DependencyProperty.RegisterAttached("ChildValidation", 
              typeof(bool), 
              typeof(ChildValidationBehavior), 
              new UIPropertyMetadata(false, OnChildValidationPropertyChanged)); 
    public static bool GetChildValidation(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(ChildValidationProperty); 
    } 
    public static void SetChildValidation(DependencyObject obj, bool value) 
    { 
     obj.SetValue(ChildValidationProperty, value); 
    } 
    private static void OnChildValidationPropertyChanged(DependencyObject dpo, 
                 DependencyPropertyChangedEventArgs e) 
    { 
     Control control = dpo as Control; 
     if (control != null) 
     { 
      if ((bool)e.NewValue == true) 
      { 
       SetErrorCount(control, 0); 
       Validation.AddErrorHandler(control, Validation_Error); 
      } 
      else 
      { 
       Validation.RemoveErrorHandler(control, Validation_Error); 
      } 
     } 
    } 
    private static void Validation_Error(object sender, ValidationErrorEventArgs e) 
    { 
     Control control = sender as Control; 
     if (e.Action == ValidationErrorEventAction.Added) 
     { 
      SetErrorCount(control, GetErrorCount(control)+1); 
     } 
     else 
     { 
      SetErrorCount(control, GetErrorCount(control)-1); 
     } 
     int errorCount = GetErrorCount(control); 
     if (errorCount > 0) 
     { 
      control.BorderBrush = Brushes.Red; 
     } 
     else 
     { 
      control.ClearValue(Control.BorderBrushProperty); 
     } 
    } 
} 
+0

太棒了。我可以看到Validation_Error正在调用,但是扩展器不更新。我有一种适用于所有扩展器的风格,这可能是责任吗? – broomyocymru 2011-02-11 10:44:22