2010-06-24 51 views
8

我目前正在爲我的WPF應用程序進行驗證,並看到提及IDataErrorInfo。然而,如何使用它的指南很少,更沒有人解釋它是如何工作的。IDataErrorInfo是如何工作的?

在MSND.com網站,這是得到安寧 MSDN

public class Person : IDataErrorInfo 
{ 
    private int age; 
    public int Age 
    { 
     get { return age; } 
     set { age = value; } 
    } 

    public string Error 
    { 
     get 
     { 
      return null; 
     } 
    } 

    public string this[string name] 
    { 
     get 
     { 
      string result = null; 
      if (name == "Age") 
      { 
       if (this.age < 0 || this.age > 150) 
       { 
        result = "Age must not be less than 0 or greater than 150."; 
       } 
      } 
      return result; 
     } 
    } 
} 

我明白是怎麼回事,但我不知道它確實給我的數據。

這兩個屬性何時使用?假設某人將Age設置爲400:調用屬性上的setter。錯誤thingy會阻止它被設置?如果沒有,它只是警告,該號碼是不正確的,什麼是阻止某人保存信息原樣?沒有IsValid()方法檢查,是嗎?

想知道窗簾會發生什麼。

回答

6

Error屬性通常不被使用,但您必須定義它以實現接口。 正如decyclone所說,驗證不會停止使用錯誤值設置屬性,但可以將屬性設置爲默認值。 讓我告訴你我是如何使用它的。我有幾個TextBox es我必須驗證他們的價值。我不想在調用set時顯示帶有錯誤的MessageBox,而是希望採用'webly'方法:當設置了無效值時,我希望TextBox的邊框和背景爲紅色,並且TextBox的工具提示爲顯示它得到的錯誤。

這是我的TextBox的XAML:

<converters:ValidationConverter x:Key="validationConverter"/> 
<Style x:Key="TestStepTextBox" TargetType="{x:Type TextBox}"> 
    <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type TextBox}"> 
       <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> 
        <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
       </Border> 
       <ControlTemplate.Triggers> 
        <Trigger Property="Validation.HasError" Value="true"> 
         <Setter Property="ToolTip" 
           Value="{Binding RelativeSource={RelativeSource Self}, 
           Converter={StaticResource validationConverter}, Path=(Validation.Errors)}"/> 
         <Setter Property="Background" Value="#33FF342D"/> 
         <Setter Property="BorderBrush" Value="#AAFF342D"/> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<TextBox Name="txtRunAfter" Text="{Binding RunAfter, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" Style="{DynamicResource TestStepTextBox}"/> 
<TextBox Name="txtStopAfter" Text="{Binding StopAfter, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" Style="{DynamicResource TestStepTextBox}"/> 

一個非常重要的注意關於交換器。當我輸入一個無效的值時,我收到了一個異常,然後我設置了一個很好的值。不知何故,或許與UpdateSourceTrigger=PropertyChanged有關,有一段時間HasError屬性爲true,但沒有設置錯誤(請參閱link)。因此,這裏是轉換器的代碼:

public class ValidationConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     ReadOnlyObservableCollection<ValidationError> errors = value as ReadOnlyObservableCollection<ValidationError>; 
     if (errors == null) return value; 
     if (errors.Count > 0) 
     { 
      return errors[0].ErrorContent; 
     } 
     return ""; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException("This method should never be called"); 
    } 
} 

爲了防止保存到我的模型層,我用同樣的方法來檢查我是否應該將數據提交到模型中的invaled值。如果該值無效,我只需設置該屬性並且不要調用模型中的一組屬性。檢查代碼:

private int _runAfter = 0; 
public int RunAfter 
{ 
    get 
    { 
     return _runAfter; 
    } 

    set 
    { 
     if (_runAfter != value) 
     { 
      _runAfter = value; 
      OnPropertyChanged("RunAfter"); 

      if (validateRunAfter() == null) 
       setRunAfter(); //sets the property value to the model layer 
     } 
    } 
} 

string IDataErrorInfo.this[string columnName] 
{ 
    get 
    { 
     string message = null; 
     if (columnName == "RunAfter") 
      message = validateRunAfter(); 
     //... 
     return message; 
    } 
} 

private string validateRunAfter() 
{ 
    if (value >= _order) 
     return "Run After value must be less than its Step Order (#) value."; 

    return null; 
} 
+0

謝謝,我沒有足夠的時間來正確檢查,但會給你正確的答案如果一切都很好;) – 2010-06-28 12:01:02

2

我知道的IDataErrorInfo它是用於UI的目的而已。它所做的是提供一種簡單的方法將錯誤消息綁定到WPF UI。由於WPF UI「標識」了實現IDataErrorInfo的對象,就像INotifyPropertyChanged一樣,您不必編寫額外的代碼來顯示UI中的錯誤消息。

還有一件事,它不會停止設置錯誤的值。它只會告訴WPF UI(當WPF UI調用提供屬性名稱的索引器)特定屬性中的值無效。

+0

除此之外,IDataErrorInfo也適用於ASP.NET MVC UI,因爲它來自System.ComponentModel http://www.asp。net/mvc/tutorials/older-versions/models-(data)/ validating-with-the-idataerrorinfo-interface-cs – Sai 2014-10-13 16:34:09