Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Naming Properties in MVVM

4.00/5 (1 vote)
24 Nov 2011CPOL 6.6K  
I use a helper class to get property names based on expressions public static class ObservableHelper { public static PropertyChangedEventArgs CreateArgs(Expression> propertyExpression) { return new...
I use a helper class to get property names based on expressions
C#
public static class ObservableHelper
{
    public static PropertyChangedEventArgs CreateArgs<t>(Expression<func><t,>> propertyExpression)
    {
        return new PropertyChangedEventArgs(GetPropertyName<t>(propertyExpression));
    }

    public static string GetPropertyName<t>(Expression<func><t,>> propertyExpression)
    {
        var lambda = propertyExpression as LambdaExpression;
        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = lambda.Body as UnaryExpression;
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = lambda.Body as MemberExpression;
        }

        if (memberExpression == null)
        {
            throw new InvalidOperationException("Lambda expression not in the correct format, use format like '() => PropertyName'");
        }

        var propertyInfo = memberExpression.Member as PropertyInfo;
        return propertyInfo.Name;
    }
}


I can call this in my class to create the PropertyChangedEventArgs, but to keep reflection calls to a minimum I declare them as static readonly fields, so for example:
C#
public class CustomersViewModel : INotifyPropertyChanged
    {
        private static readonly PropertyChangedEventArgs idArgs = ObservableHelper.CreateArgs<customersviewmodel>(x => x.Id);
        private static readonly PropertyChangedEventArgs nameArgs = ObservableHelper.CreateArgs<customersviewmodel>(x => x.Name);
        
        private int id;
        private string name;

        public int Id
        {
            get { return this.id; }
            set
            {
                if (this.id != value)
                {
                    this.id = value;
                    this.OnPropertyChanged(idArgs);
                }
            }
        }

        public string Name
        {
            get { return this.name; }
            set
            {
                if (this.name != value)
                {
                    this.name = value;
                    this.OnPropertyChanged(nameArgs);
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(PropertyChangedEventArgs args)
        {
            if (this.PropertyChanged != null) 
            {
                this.PropertyChanged(this, args);
            }
        }
    }


I don't really know if the reflection calls are really a huge performance loss in this, but no more magical strings and save to rename properties.
- Edited because I remembered that this is something I saw in Cinch framework from Sacha Barber, so all credit should go to him ;-)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)