WPF Validation - Using INotifyDataErrorInfo | .NET Land (kmatyaszek.github.io)
WPF Validation - Using INotifyDataErrorInfo | .NET Land (kmatyaszek.github.io)
In the .NET 4.5 was introduced new interface INotifyDataErrorInfo
which enables data entity classes to implement custom validation rules and expose validation results asynchronously. This interface has three members:
HasErrors
property indicates whether there are any validation errorsGetErrors
method returns anIEnumerable
that contains validation errors for the specified property (when the propertyName parameter isn’t equal to null or empty string) or for the entire entity (when the propertyName parameter is equal to null or empty string)ErrorsChanged
event must occur when the validation errors have changed for a property or for the entity
As GetErrors
returns IEnumerable
you can return multiple errors per property. Also, you can return custom error object (this is not possible using IDataErrorInfo
interface). As you can see this new interface provides more flexible validation model in WPF. By default, ValidatesOnNotifyDataErrors
is set to true so you don’t have to set this explicit in the binding expression. Below you can see the result of my example program (as you can see TextBox
has two errors).
Below you can see an example implementation of the INotifyDataErrorInfo
:
public class MainViewModel : BindableBase, INotifyDataErrorInfo
{
private string _userName;
private readonly Dictionary<string, List<string>> _errorsByPropertyName = new Dictionary<string, List<string>>();
public MainViewModel()
{
UserName = null;
}
public string UserName
{
get => _userName;
set
{
_userName = value;
ValidateUserName();
RaisePropertyChanged();
}
}
public bool HasErrors => _errorsByPropertyName.Any();
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public IEnumerable GetErrors(string propertyName)
{
return _errorsByPropertyName.ContainsKey(propertyName) ?
_errorsByPropertyName[propertyName] : null;
}
private void OnErrorsChanged(string propertyName)
{
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
private void ValidateUserName()
{
ClearErrors(nameof(UserName));
if (string.IsNullOrWhiteSpace(UserName))
AddError(nameof(UserName), "Username cannot be empty.");
if (string.Equals(UserName, "Admin", StringComparison.OrdinalIgnoreCase))
AddError(nameof(UserName), "Admin is not valid username.");
if (UserName == null || UserName?.Length <= 5)
AddError(nameof(UserName), "Username must be at least 6 characters long.");
}
private void AddError(string propertyName, string error)
{
if (!_errorsByPropertyName.ContainsKey(propertyName))
_errorsByPropertyName[propertyName] = new List<string>();
if (!_errorsByPropertyName[propertyName].Contains(error))
{
_errorsByPropertyName[propertyName].Add(error);
OnErrorsChanged(propertyName);
}
}
private void ClearErrors(string propertyName)
{
if (_errorsByPropertyName.ContainsKey(propertyName))
{
_errorsByPropertyName.Remove(propertyName);
OnErrorsChanged(propertyName);
}
}
}
And below snippet of code shows you how you can show to user multiple errors to single property:
A complete example is available on the following link: https://github.com/kmatyaszek/WPFValidationINotifyDataErrorInfo
WPF validation using INotifyDataErrorInfo - Dot Net For All
In this article I will discuss about INotifyDataErrorInfo which is used to validate the data asynchronously in WPF. In my previous articles I have discussed about the ways to validate data entered in the UI.
Please find the previous articles link below
Validation using INotifyDataErrorInfo
- Added in .NET 4.5 for WPF
- It works on the same principle as IDataErrorInfo but it is based on the event driven mechanism which notifies for the validation errors asynchronously based on the input from some time consuming operation like service call. It will wait for the results to come back and eventually it will raise the event.
- Set ValidatesOnNotifyDataErrors=True on binding.
- Binding will call the GetErrors method of the INotifyDataErrorInfo when the property is set in the ViewModel through view.
- Binding also subscribes to the ErrorsChanged event in the interface.
- If the ErrorsChanged event is raised, it will go and re query the GetErrors method for the property for which the event is raised.
- To implement this we need to manage a dictionary of errors per property as part of error.
- One of the advantage of this over IDataErrorInfo is that we can return multiple errors per property.
The interface has three members which the derived class need to implement. Whenever we are setting this validation, the HasErrors property is called by the binding which in turn calls the GetErrors method to return the error if the HasErrors return true. After some point when GetErrors is called the ErrorsChanged event is raised and it again calls GetErrors method. It is assuming that there are some asynchronous operation that filled the collection on which the GetErrors is working on.
As we can see the GetErrors method return the IEnumerable object. It means that it is working on some collection of the objects to get the errors.
相关文章
- WPF入门教程系列二——Application介绍
- c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习
- 连表查询都用Left Join吧 以Windows服务方式运行.NET Core程序 HTTP和HTTPS的区别 ASP.NET SignalR介绍 asp.net—WebApi跨域 asp.net—自定义轻量级ORM C#之23中设计模式
- Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
- wpf 导出Excel Wpf Button 样式 wpf简单进度条 List泛型集合对象排序 C#集合
- C#字符串数组排序 C#排序算法大全 C#字符串比较方法 一个.NET通用JSON解析/构建类的实现(c#) C#处理Json文件 asp.net使用Jquery+iframe传值问题
- 演练:我的第一个 WPF 桌面应用程序 https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/getting-started/walkthrough-my-first-wpf-desktop-application
- WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化
- 【wpf】Image 图片绑定/更新
- 【wpf】<i:Interaction.Triggers> 相关报错
- 【wpf】Initialized 事件的使用
- 创建WPF项目
- C#-abo.net-Data Tracing in ADO.NET
- asp.net-Creating JavaScript objects from ASP.NET objects
- asp.net-Creating JavaScript objects from ASP.NET objects
- 【WPF】右键菜单ContextMenu可点击区域太小的问题
- 【WPF】修改数据层ViewModel后,UI界面未同步更新
- 【WPF】MVVM动态修改Bingding的另一种思路——用Style样式
- 【C#/WPF】.Net生成二维码QRCode的工具
- 【C#/WPF】TextBlock/TextBox/Label编辑文字的问题
- 【WPF/C#】联网异步获取二进制文件(如图片)的流程
- 【WPF】设置TextBox内容为空时的提示文字