Usese MVVM Light
namespace MonitorMessageGenerator.Code
{
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;
public abstract class MyViewModelBase : ViewModelBase, INotifyDataErrorInfo
{
private readonly object @lock = new object();
private readonly ConcurrentDictionary<string, List<string>> errors = new ConcurrentDictionary<string, List<string>>();
protected virtual void OnPropertyChanged([CallerMemberName] string name = null)
{
var e = PropertyChangedHandler;
if (e != null)
e(this, new PropertyChangedEventArgs(name));
ValidateAsync();
}
protected async void ValidateAsync()
{
await Task.Run(() => Validate());
}
public virtual void Validate()
{
lock (@lock)
{
var validationContext = new ValidationContext(this, null, null);
var validationResults = new List<ValidationResult>();
Validator.TryValidateObject(this, validationContext, validationResults, true);
foreach (var kv in errors.ToList())
{
if (validationResults.All(r => r.MemberNames.All(m => m != kv.Key)))
{
List<string> outLi;
errors.TryRemove(kv.Key, out outLi);
OnErrorsChanged(kv.Key);
}
}
var q = from r in validationResults
from m in r.MemberNames
group r by m into g
select g;
foreach (var prop in q)
{
var messages = prop.Select(r => r.ErrorMessage).ToList();
if (errors.ContainsKey(prop.Key))
{
List<string> outLi;
errors.TryRemove(prop.Key, out outLi);
}
errors.TryAdd(prop.Key, messages);
OnErrorsChanged(prop.Key);
}
}
}
public IEnumerable GetErrors(string propertyName)
{
List<string> errorsForName;
errors.TryGetValue(propertyName, out errorsForName);
return errorsForName;
}
public bool HasErrors
{
get { return @errors.Any(kv => kv.Value != null && kv.Value.Count > 0); }
}
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
protected virtual void OnErrorsChanged(string propertyName)
{
var e = ErrorsChanged;
if (e != null)
e(this, new DataErrorsChangedEventArgs(propertyName));
}
}
}