65.9K
CodeProject is changing. Read more.
Home

Naming Properties in MVVM

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1 vote)

Nov 24, 2011

CPOL
viewsIcon

6561

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
    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:
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 ;-)