HowToImpleteINotifyDataErrors
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 OnErrorHappened([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);
OnErrorHappened(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>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)