Please look below for my example:
Model class implements INotifyPropertyChanged
public class ModelClass : INotifyPropertyChanged
{
private string destinationCity;
public string SourceCity { get; set; }
public ModelClass()
{
PropertyChanged += CustomAttribute.ThrowIfNotEquals;
}
[Custom("SourceCity", ErrorMessage = "the source and destination should not be equal")]
public string DestinationCity
{
get
{
return this.destinationCity;
}
set
{
if (value != this.destinationCity)
{
this.destinationCity = value;
NotifyPropertyChanged("DestinationCity");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
Attribute class also contains event hendler.
internal sealed class CustomAttribute : Attribute
{
public CustomAttribute(string propertyName)
{
PropertyName = propertyName;
}
public string PropertyName { get; set; }
public string ErrorMessage { get; set; }
public static void ThrowIfNotEquals(object obj, PropertyChangedEventArgs eventArgs)
{
Type type = obj.GetType();
var changedProperty = type.GetProperty(eventArgs.PropertyName);
var attribute = (CustomAttribute)changedProperty
.GetCustomAttributes(typeof(CustomAttribute), false)
.FirstOrDefault();
var valueToCompare = type.GetProperty(attribute.PropertyName).GetValue(obj, null);
if (!valueToCompare.Equals(changedProperty.GetValue(obj, null)))
throw new Exception("the source and destination should not be equal");
}
}
Usage
var test = new ModelClass();
test.SourceCity = "1";
// Everything is ok
test.DestinationCity = "1";
// throws exception
test.DestinationCity ="2";
To simplify code I decided to omit a validation.