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 one rrorsChanged(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);
one rrorsChanged(propertyName);
}
}
private void ClearErrors(string propertyName)
{
if (_errorsByPropertyName.ContainsKey(propertyName))
{
_errorsByPropertyName.Remove(propertyName);
one rrorsChanged(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.
标签:GetErrors,Land,propertyName,github,INotifyDataErrorInfo,property,errors,validati From: https://www.cnblogs.com/chucklu/p/17201072.html