如果我正确理解您的问题,您可以使用以下内容:
public static class PropertyChangedExtensions
{
public static void RegisterPropertyHandler<T, TProperty>(this T obj, Expression<Func<T, TProperty>> propertyExpression, PropertyChangedEventHandler handlerDelegate)
where T : class, INotifyPropertyChanged
{
if (obj == null) throw new ArgumentNullException("obj");
var propertyName = GetPropertyName(propertyExpression);
obj.PropertyChanged += (sender, args) =>
{
if (args.PropertyName == propertyName && handlerDelegate != null)
handlerDelegate(sender, args);
};
}
public static void Notify<T>(this PropertyChangedEventHandler eventHandler, object sender, Expression<Func<T>> propertyExpression)
{
var handler = eventHandler;
if (handler != null) handler(sender, new PropertyChangedEventArgs(GetPropertyName(propertyExpression)));
}
private static string GetPropertyName(LambdaExpression propertyExpression)
{
var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
var unaryExpression = propertyExpression.Body as UnaryExpression;
if (unaryExpression == null)
throw new ArgumentException("Expression must be a UnaryExpression.", "propertyExpression");
memberExpression = unaryExpression.Operand as MemberExpression;
}
if (memberExpression == null)
throw new ArgumentException("Expression must be a MemberExpression.", "propertyExpression");
var propertyInfo = memberExpression.Member as PropertyInfo;
if (propertyInfo == null)
throw new ArgumentException("Expression must be a Property.", "propertyExpression");
return propertyInfo.Name;
}
}
该RegisterPropertyHandler
方法允许您在不使用“魔术字符串”的情况下为特定属性注册处理程序。你像这样使用它:
public class PersonViewModel : INotifyPropertyChanged
{
public PersonViewModel()
{
Address = new AddressViewModel();
Address.RegisterPropertyHandler(a => a.ZipCode, ZipCodeChanged);
}
private AddressViewModel _address;
public AddressViewModel Address
{
get { return _address; }
set
{
_address = value;
PropertyChanged.Notify(this, () => Address);
}
}
private static void ZipCodeChanged(object sender, PropertyChangedEventArgs args)
{
// This will only be called when the 'ZipCode' property of 'Address' changes.
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class AddressViewModel : INotifyPropertyChanged
{
private string _zipCode;
public string ZipCode
{
get
{
return _zipCode;
}
set
{
_zipCode = value;
PropertyChanged.Notify(this, () => ZipCode);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
我看到你已经有一个Notify
扩展方法,所以你只需要添加RegisterPropertyHandler
. 至少这是一个开始:)