Как работает IDataErrorInfo?
в настоящее время я изучаю проверку для моего приложения WPF и видел упоминание 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;
}
}
}
Я вижу, что здесь происходит, но я понятия не имею, что это действительно в моих данных.
когда используются эти 2 свойства? Допустим, кто-то устанавливает Age
as 400: сеттер в свойстве называемый. Будет ли ошибка thingy остановить его от установки? Если нет, и он просто предупреждает, что номер неверен, что может остановить кого-то от сохранения информации как есть? Нет IsValid()
метод проверки, есть?
хотелось бы знать, что происходит за занавесками.
2 ответов
The Error
свойство обычно не используется, но вы должны определить его для реализации интерфейса.
Как сказал дециклон, проверка не остановит свойство от установки с неправильным значением, но вы можете установить свойство в значение по умолчанию.
Позвольте показать вам, как я его использую. У меня есть пара TextBox
es, что я должен проверить значения, которые у них есть. Вместо того, чтобы показывать MessageBox с ошибкой при вызове набора, я хочу использовать подход "webly": я хочу границу и фон TextBox
быть красным, когда установлено недопустимое значение и всплывающая подсказка TextBox
чтобы показать ошибку, которую он получил.
это мой xaml для TextBox:
<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}"/>
A очень важно о конвертере. Я получал исключение, когда я ввел недопустимое значение, а затем установил хорошее значение. Как-то, может быть, связано с наличием UpdateSourceTrigger=PropertyChanged
, было время, когда свойство HasError было true, но не было набора ошибок (см. ссылке). Итак, вот код для конвертера:
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;
}