避免在PropertyChanged上进行级联操作

时间:2014-08-15 13:40:58

标签: c# .net inotifypropertychanged

假设我有这个模型:

public sealed class Model : ModelBase // base is a INotifyPropertyChanged implementation
{        
    private void SomeAction()
    {
        Console.WriteLine("SomeAction!");
    }

    protected override void OnPropertyChanged(string propertyName)
    {
        base.OnPropertyChanged(propertyName);

        switch (propertyName)
        {
            case "A":
                B = A + 1;
                SomeAction();
                break;
            case "B":
                SomeAction();
                break;
        }
    }

    public int A
    {
        get { return a; }
        set
        {
            if (a != value)
            {
                a = value;
                OnPropertyChanged("A");
            }
        }
    }
    private int a;

    public int B
    {
        get { return b; }
        set
        {
            if (b != value)
            {
                b = value;
                OnPropertyChanged("B");
            }
        }
    }
    private int b;      
}

以下是两个属性:ABB取决于A - 当A的值发生变化时,B也必须更改。无论如何,当更改任何这些属性时,应该执行SomeAction

显然,我希望在更改SomeAction时避免两次A来电 有没有优雅的方法来做到这一点(某种布尔标志不是一种优雅的方式)?

UPD

我应该提一下,我正在寻找比下面答案中提供的更通用的解决方案。原因是当属性数量增加时,代码复杂性增长得更快。例如,这些图表 - D< - C< - A - > B - 会导致代码无法轻松维护。

3 个答案:

答案 0 :(得分:1)

您可以在每个属性设置器中调用SomeAction

public int A
{
    get { return a; }
    set
    {
        if (a != value)
        {
            a = value;
            b = value + 1;
            OnPropertyChanged("A");
            OnPropertyChanged("B");
            SomeAction();
        }
    }
}
private int a;

public int B
{
    get { return b; }
    set
    {
        if (b != value)
        {
            b = value;
            OnPropertyChanged("B");
            SomeAction();
        }
    }
}
private int b;      

答案 1 :(得分:0)

    switch (propertyName)
    {
        case "A":
            //Change the Private b instead of B so it won't call SomeAction twice.
            b = A + 1;
            SomeAction();
            break;
        case "B":
            SomeAction();
            break;
    }

答案 2 :(得分:0)

您是否将多个属性更改视为单个操作的标准似乎是:"是否在OnPropertyChanged方法中处理?"但是这个方法也只是首先负责调用动作,所以......为什么不设计OnPropertyChanged来避免级联呢?它应该像删除其中一个调用一样简单:

case "A":
    B = A + 1;
    break;
case "B":
    SomeAction();
    break;

我不知道这是不优雅的,因为所有逻辑都局限于单一方法。你基本上有一个递归方法,其中" B"是终止条件。