Pages

An elegant way to write WPF Models and ViewModels


An elegant way to write WPF Models and ViewModels

In WPF, to send notification of value changed of model’s property to view, you must have to implement  INotifyPropertyChanged interface. Here in following example, ViewModelbase has implementation of INotifyPropertyChanged so when you inherit from ViewModelbase class to your models and ViewModels, you no need to re-implement same interface again. This class has  NotifyPropertyChanged ovverloaded methods which allows you to send notification to view with and without value compare.

public abstract class ViewModelbase : INotifyPropertyChanged
{
    protected void NotifyPropertyChanged<T>(Expression<Func<T>> memberExpression)
    {
        if (memberExpression == null)
        {
            throw new ArgumentNullException("memberExpression");
        }
            
        var body = memberExpression.Body as MemberExpression;
            
        if (body == null)
        {
            throw new ArgumentException("Lambda must return a property.");
        }
 
        if (PropertyChanged != null)
        {
            var vmExpression = body.Expression as ConstantExpression;
            if (vmExpression != null)
            {
                var lambda = Expression.Lambda(vmExpression);
                var vmFunc = lambda.Compile();
                var sender = vmFunc.DynamicInvoke();
                PropertyChanged(sender, new PropertyChangedEventArgs(body.Member.Name));
            }
        }            
    }
 
    protected void NotifyPropertyChanged<T>(Expression<Func<T>> memberExpression, ref T oldValue, ref T newValue)
    {
        if (EqualityComparer<T>.Default.Equals(oldValue, newValue))
        {
            return;
        }
        NotifyPropertyChanged(memberExpression);
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
}
 

Inherit person class from ViewModelbase

 
public class Person : ViewModelbase
{
    private string _name;
 
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            NotifyPropertyChanged(()=>Name);
        }
    }
 
    private int _age;
 
    public int Age
    {
        get { return _age; }
        set
        {
            NotifyPropertyChanged(() => Age, ref _age, ref value);
            _age = value;
        }
    }