安全订阅PropertyChanged

时间:2013-11-26 13:24:03

标签: c# inotifypropertychanged

我有以下方法:

void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    switch (e.PropertyName)
    {
        case "InitializeFailureMessage":
            if (Vm.InitializeFailureMessage != null)
                ShowInitializeFailure(Vm.InitializeFailureMessage);
            break;
    }
}

刚才,该方法有一个错误:该属性曾被称为InitializeFailureErrorMessage,当它被重命名时,没有人更新此处理程序中的字符串。

订阅PropertyChanged事件是否有更好,更不容易出错的方式?在触发事件时,我们现在可以使用[CallerMemberName]。实现处理程序时是否有类似的技巧?

2 个答案:

答案 0 :(得分:2)

使用扩展方法,表达式和委托的快速构思:

public static class Extension
{
    public static void RegisterNotify<T>(this T obj, Expression<Func<T, object>> propExpr, Action action) where T : INotifyPropertyChanged
    {
        string name = GetPropertyName(propExpr);
        obj.PropertyChanged += (s, e) => { if (e.PropertyName == name) action() };
    }
}

它被称为:

    Notifier obj = new Notifier(); // implements INotifyPropertyChanged
    obj.RegisterNotify(x => x.Property, () => { /* do something when Property changes */ });
    obj.RegisterNotify(x => x.Property2, () => { /* do something else when Property2 changes */ });

答案 1 :(得分:1)

使用this实用程序方法使用Expressions.

获取属性名称

考虑这是你的类触发事件,引入一个static readonly string field来告诉字符串表示属性。然后使用该静态字段来检查属性已更改的内容。

class MyClass
{
    public static readonly string InitializeFailureMessageProperty = GetPropertyName(() => x.InitializeFailureMessageProperty);//x can be a dummy instance.
}

void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == MyClass.InitializeFailureMessageProperty)
    {
         if (Vm.InitializeFailureMessage != null)
             ShowInitializeFailure(Vm.InitializeFailureMessage);
    }
}