为级联只读属性避免重复的RaisePropertyChanged

时间:2017-09-20 06:23:15

标签: c# mvvm viewmodel inotifypropertychanged

我的视图模型中有几个只读属性,由View引用,其中一些依赖于一个/多个其他只读属性(在同一个视图模型中),这些属性最终依赖于一个/多个读/写属性(在相同的视图模型中)。我在样本中只看到了以下模式,以确保为所有可能受影响的属性引发PropertyChanged事件,但我不喜欢复制所有这些RaisePropertyChanged调用。

我怀疑我应该在View模型的PropertyChanged事件和Handler中添加一个Handler,对于每个具有依赖属性的Property,只在直接的属性上调用RaisePropertyChanged (与间接相关的那些)依赖于该属性。如何避免重复所有RaisePropertyChanged调用?

public bool MyReadOnlyPropertyAA1
{
    get
    {
        return MyReadOnlyPropertyA1 [&& MyReadOnlyPropertyB1 ...]
    }
}


public bool MyReadOnlyPropertyA1
{
    get
    {
        return (MyPropertyA == (Some Value)) [&& MyPropertyB == (Some Other Value)) ... ]
    }
}

public MyPropertyAType MyPropertyA
{
    get
    {
        return myPropertyA
    }
    set
    {
        myPropertyA = value;
        RaisePropertyChanged(nameof(MyPropertyA));  
        RaisePropertyChanged(nameof(MyReadOnlyPropertyA));
        RaisePropertyChanged(nameof(MyReadOnlyPropertyA1));
        RaisePropertyChanged(nameof(MyReadOnlyPropertyAA1));
        ...
        RaisePropertyChanged(nameof(MyReadOnlyPropertyAA...1));
    }
}


public MyPropertyBType MyPropertyB
{
    get
    {
        return myPropertyB
    }
    set
    {
        myPropertyB = value;
        RaisePropertyChanged(nameof(MyPropertyB));  
        RaisePropertyChanged(nameof(MyReadOnlyPropertyA));
        RaisePropertyChanged(nameof(MyReadOnlyPropertyA1));
        RaisePropertyChanged(nameof(MyReadOnlyPropertyAA1));
        ...
        RaisePropertyChanged(nameof(MyReadOnlyPropertyAA...1));
    }
 }

1 个答案:

答案 0 :(得分:3)

我根据属性关系使用这两种方法。

如果更改一个属性会触发另一个属性的更改是合乎逻辑的,我只需将属性更改代码留在setter中。

public string PropertyA
{
    get { return propertyA; }
    set
    {
        myPropertyA = value;
        RaisePropertyChanged(nameof(PropertyA));  
        RaisePropertyChanged(nameof(IsPropertyAValid));
        ...
    }
}

但是如果这两个属性在逻辑上不相关,那么我将使用PropertyChange处理程序:

private void MyClass_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    switch(e.PropertyName)
    {
        case "PropertyA":
            RaisePropertyChanged(nameof(PropertyB));
            break;
    }
}

原因是我想在我的属性设置器中没有特殊的逻辑。对我来说,它们应该是相当通用的,卡在#region标签中,然后崩溃而被遗忘。

如果两个属性在逻辑上相关,并且您希望更改一个属性可能会改变另一个属性的值,那么RaisePropertyChange代码可以保留在setter中。

但是如果它们不同,并且将来我自己或其他开发人员正在查看代码并且可能不知道/理解两者之间存在依赖关系,那么我将改变放在课堂上' ■PropertyChange事件处理程序,以便在必要时轻松查找和/或更改。