A better use of INotifyPropertyChanged in Silverlight using MVVM style

 

Working with Silverlight requires notification change, in other word we need to explicitly notify client that a changed occurs. For that you need to implement INotifyPropertyChanged (see the link for more details).

When you implement this interface, you are constraint to provide the property name as a string. This is error prone because when you rename your property (depends how you rename your properties) you can miss all the occurrences of the name.

The trick is to use INotifyPropertyChanged in combination with expression trees and lambda expression.

public static string GetMethodName(Expression<Func<object, object>> property)

{

   var expr = (((System.Linq.Expressions.LambdaExpression)(property)).Body);

   string method = string.Empty;

 

   if (expr is UnaryExpression)

   {

       method = 

           (((System.Linq.Expressions.MemberExpression)

           (((System.Linq.Expressions.UnaryExpression)

           (((System.Linq.Expressions.LambdaExpression)(property)).Body)).Operand)).Member).Name;

   }

   else if (expr is MemberExpression)

   {

       method = (((System.Linq.Expressions.MemberExpression)

                (((System.Linq.Expressions.LambdaExpression)(property)).Body)).Member).Name;

   }

 

   return method;

}

 

This method is very useful to extract the property name and than passed it to the INotifyPropertyChanged event argument.

public class BaseModel : INotifyPropertyChanged

{

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyProperty(string propertyName)

    {

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        }

    }

 

    protected void NotifyProperty(Expression<Func<object, object>> property)

    {

        string method = Common.ExpressionHelper.GetMethodName(property);

 

        if (!string.IsNullOrEmpty(method))

        {

            this.NotifyProperty(method);

        }

    }

}

You can call it like this:

this.NotifyProperty(i => this.MyProperty);

This ensure you that whenever rename a property