how to implement INotifyDataErrorInfo MVVM
目前实现data validation 有两种方式,一种是通过xaml, 还有就是通过viewmodel.
xaml的实现方式如下。这种情况下,viewmodel不需要写任何代码,但是viewmodel在写逻辑时,在获取某个property是否通过验证时不方便,需要做二次值检查。不推荐。
<TextBox
Margin="2"
attachedClasses:HeaderedElement.EndContent="(必填)"
attachedClasses:HeaderedElement.Header="批次Id:">
<TextBox.Text>
<Binding
Mode="TwoWay"
NotifyOnValidationError="True"
Path=" LotNumber"
UpdateSourceTrigger="PropertyChanged"
ValidatesOnDataErrors="True"
ValidatesOnNotifyDataErrors="True">
<Binding.ValidationRules>
<validations:StringNotNullRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<hc:Interaction.Triggers>
<hc:RoutedEventTrigger RoutedEvent="{x:Static Validation.ErrorEvent}">
<hc:EventToCommand Command="{Binding OnValidationErrorOccurredCommand}" PassEventArgsToCommand="True" />
</hc:RoutedEventTrigger>
</hc:Interaction.Triggers>
</TextBox>
*** 以viewmodel为主的方法如下,另外实现数据验证一个接口 IDataErrorInfo
,这个接口较老,不推荐使用。
public class ViewModelClass:InotifyPropertyChanged,INotifyDataErrorInfo
{
private string _operatorId;
//demo property
public string OperatorId
{
get => _operatorId;
set
{
SetProperty(ref _operatorId, value);
if (string.IsNullOrEmpty(value))
{
AddError($"{nameof(OperatorId)} cannot be empty.");
}
else
{
CancelError();
}
}
}
private readonly Dictionary<string, IList<string>> _errors = new Dictionary<string, IList<string>>();
public IEnumerable GetErrors(string? propertyName)
{
return _errors.GetValueOrDefault(propertyName, null);
}
public bool HasErrors { get => _errors.Any(); }
public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;
private void one rrorHappened([CallerMemberName] string propertyName = "")
{
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
public void AddError(string errorMessage, [CallerMemberName] string propertyName = "")
{
if (!_errors.ContainsKey(propertyName))
{
_errors.Add(propertyName, new List<string>());
}
_errors[propertyName].Add(errorMessage);
one rrorHappened(propertyName);
}
private void CancelError([CallerMemberName] string propertyName = "")
{
if (!_errors.ContainsKey(propertyName))
{
_errors.Add(propertyName, new List<string>());
}
_errors[propertyName].Clear();
}
}
xaml
<TextBox
Margin="2"
Text="{Binding OperatorId, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
styl
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
另外
也可使用 error template
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
<AdornedElementPlaceholder/>
</DockPanel>
</ControlTemplate>
然后在textbox中指定error template
<TextBox Name="textBox1" Width="50" FontSize="15"
Validation.ErrorTemplate="{StaticResource ValidationTemplate}"
Style="{StaticResource TextBoxInError}"
Grid.Row="1" Grid.Column="1" Margin="2">
<TextBox.Text>
<Binding Path="Age" Source="{StaticResource Ods}"
UpdateSourceTrigger="PropertyChanged" >
<Binding.ValidationRules>
<local:AgeRangeRule Min="21" Max="130"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
标签:errors,HowToImpleteINotifyDataErrors,propertyName,private,new,public,string
From: https://www.cnblogs.com/baibaisheng/p/16820964.html