-
Notifications
You must be signed in to change notification settings - Fork 11
Inheriting your class from IValidatableObject
Vsevolod Pilipenko edited this page Jul 19, 2022
·
2 revisions
Inheritors of IValidatableObject
must also implement INotifyPropertyChanged
and INotifyDataErrorInfo
.
If your class has already inherited INotifyPropertyChanged
you can just add next code to your class (this code from ValidatableObject class):
private IObjectValidator? _objectValidator;
/// <inheritdoc />
public IObjectValidator? Validator
{
get => _objectValidator;
set
{
_objectValidator?.Dispose();
_objectValidator = value;
_objectValidator?.Revalidate();
}
}
/// <inheritdoc />
public virtual void OnPropertyMessagesChanged(string propertyName)
{
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
#region INotifyDataErrorInfo
/// <inheritdoc />
bool INotifyDataErrorInfo.HasErrors => Validator?.IsValid == false || Validator?.HasWarnings == true;
/// <inheritdoc />
public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;
/// <inheritdoc />
IEnumerable INotifyDataErrorInfo.GetErrors(string? propertyName)
{
if (Validator == null)
return Array.Empty<ValidationMessage>();
return string.IsNullOrEmpty(propertyName)
? Validator.ValidationMessages
: Validator.GetMessages(propertyName!);
}
#endregion
If your class doesn't inherit from INotifyPropertyChanged
, you can easily define it with additional code (which taken from BaseNotifyPropertyChanged class):
/// <inheritdoc />
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
/// Raise <see cref="PropertyChanged" /> event.
/// </summary>
/// <param name="propertyName">Name of property.</param>
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// If new value not equal old, set new value and raise <see cref="PropertyChanged" /> event.
/// </summary>
/// <typeparam name="TProp">Type of property.</typeparam>
/// <param name="field">Field of property.</param>
/// <param name="value">New value.</param>
/// <param name="propertyName">Name of property.</param>
protected virtual void SetAndRaiseIfChanged<TProp>(ref TProp field, TProp value, [CallerMemberName] string? propertyName = null)
{
if (Equals(field, value))
return;
field = value;
OnPropertyChanged(propertyName);
}