2011-02-08 83 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