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