2010-06-24 58 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