C# 避免为级联只读属性更改重复的RaiseProperty

C# 避免为级联只读属性更改重复的RaiseProperty,c#,mvvm,viewmodel,inotifypropertychanged,C#,Mvvm,Viewmodel,Inotifypropertychanged,我的视图模型中有几个只读属性,这些属性由视图引用,其中一些依赖于同一视图模型中的一个/多个其他只读属性,而这些只读属性最终依赖于同一视图模型中的一个/多个读/写属性。我在示例中只看到了以下模式,以确保为所有可能受影响的属性引发PropertyChanged事件,但我不喜欢重复所有这些RaisePropertyChanged调用 我怀疑我应该改为在视图模型的PropertyChanged事件中添加一个处理程序,在该处理程序中,对于具有依赖属性的每个属性,只对直接依赖该属性的属性调用RaisePro

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

我怀疑我应该改为在视图模型的PropertyChanged事件中添加一个处理程序,在该处理程序中,对于具有依赖属性的每个属性,只对直接依赖该属性的属性调用RaisePropertyChanged,而对间接依赖该属性的属性调用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));
    }
 }

我根据财产关系使用这两种方法

如果更改一个属性会触发另一个属性的更改是合乎逻辑的,那么我只需将属性更改代码保留在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;
    }
}
原因是我不想在我的属性设置器中使用特殊的逻辑。对我来说,它们应该是相当通用的,卡在一个区域标记中,然后折叠起来被遗忘

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


但是如果它们是不同的,将来我或其他开发人员在查看代码时可能不知道/不理解两者之间存在依赖关系,我将更改放在类的PropertyChange事件处理程序中,以便在必要时易于查找和/或更改。

为只读属性触发属性更改事件是愚蠢的高度。如果您给代码用户的印象是属性是只读的,就让它保持这种状态。设计不应使更改某些其他属性对it@MickyD仅仅因为属性是只读的,并不意味着属性的值是常量。这只是意味着你不能通过setter来修改属性。@MickyD为什么,仅仅为了获得一些信息,例如concat两个字符串,或者一个简单的计算,一个方法不会有多大帮助。拥有一个属性可以让你很容易地绑定你的派生信息。我不知道为什么你会得到一大堆反对票,但我最好的猜测是这是一条线什么是一些/是最好的方式。。。。这里的人们有时把这种方式看得太字面了,认为这是在要求列出一系列事情,所以不要因为过于宽泛而投赞成票。我建议您的核心问题更加具体,例如如何避免在属性设置器中重复RaisePropertyChanged调用?。就我个人而言,我不认为这是一个坏问题,这是我早年可能问过的问题。@Rachel:谢谢!我做了编辑。显然,在这样的情况下,这样问确实很痛苦!。嘘!首先,叹气,很抱歉你被否决了,IMHO,这是一个体面的回答。我认为否决票应该留给那些恶意的问题、评论和答案。否则,让缺乏/较少的赞成票为自己说话,即正面强化与负面强化。我会暂缓把它作为答案,看看是否还有其他答案。FWIW,我对它进行了投票,因此它将抵消至少一个希望只有过去/未来的否决票。再想一想,如果只读属性仅从读/写属性中删除了1级,然后,无论是在读/写属性的设置程序中还是在属性更改事件处理程序中完成,RaisePropertyChange调用都是一样的。当只读属性被删除2+级时,在读/写属性设置器中这样做会引入重复。这些就是我要问的场景。正如我在回答其他人的问题之前的评论中提到的,除了避免重复之外,将依赖属性的RaisePropertyChange移到属性的Setter之外的另一个原因是为了避免什么,IMHO,是一个问题,称之为SoC或其他问题,其中引发PropertyChanged事件的属性是依赖项,而不是引发它们的属性的依赖项。这些属性不应该知道它们的依赖项是什么,就像ViewModel属性不应该知道哪些视图元素依赖于它们一样。您对此有何想法?@Tom在这种情况下,只需使用PropertyChanged事件处理程序来侦听对从属属性的更改,并根据需要发出关联的更改通知。我尝试编辑您的答案,以包括当只读属性从被引用的读/写属性中删除2+个级别时避免重复的RaisePropertyChange调用的用例,但编辑被拒绝。如果您愿意,请编辑您的A 如果要包括这一点,我会接受它作为答案。谢谢!