传递Action而不是挂钩PropertyChanged?

时间:2013-11-12 15:06:03

标签: c# wpf mvvm action propertychanged

在我目前的项目中,我遇到了以下情况:

  • VM1用于在屏幕上显示。
  • VM1的公共属性为VM2。
  • VM1具有VM3的公共属性。
  • VM3的属性取决于VM2。
  • VM1没有处置机制。

一开始我想到挂钩到VM2.PropertyChanged事件以检查我想要的属性并相应地更改受VM3影响的属性,如:

public class VM1 : INotifyPropertyChanged
{
    public property VM2 VM2 { get; private set; }
    public property VM3 VM3 { get; private set; }

    public VM1()
    {
        this.VM2 = new VM2();
        this.VM3 = new VM3();
        this.VM2.PropertyChanged += this.VM2_PropertyChanged;
    }

    private void VM2_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        // if e.PropertyName equals bla then VM3.SomeProperty = lol.     
    }
}

这意味着,由于我无法解开此类中的事件,因此我有内存泄漏。

所以我最终将一个Action传递给VM2,以便在其重要属性更改值时调用它,如:

public class VM2 : INotifyPropertyChanged
{
    public Action WhenP1Changes { get; set; }

    private bool _p1;
    public bool P1
    {
        get
        {
            return _p1;
        }
        set
        {
            _p1 = value;
            this.WhenP1Changes();
            this.PropertyChanged(this, new PropertChangedEventArgs("P1");
        }
    }
}

public class VM1 : INotifyPropertyChanged
{
    public VM2 VM2 { get; private set; }
    public VM3 VM3 { get; private set; }

    public VM1()
    {
        this.VM2 = new VM2();
        this.VM3 = new VM3();
        this.VM2.WhenP1Changes = () => VM3.SomeProperty = "lol";
    }
}

我这里有内存泄漏吗?

PD:如果您还能回答以下问题,那就太好了:   - 这是一个好习惯吗?

由于

2 个答案:

答案 0 :(得分:1)

简而言之,我更愿意使用delegate在视图模型之间进行通知。如果您有一个父视图模型可以访问各种子视图模型(似乎您这样做),那么您可以使用一个或多个delegate类事件来在需要更新时通知对方。

我不想再次输入整个场景,而是指向我对Passing parameters between viewmodels问题的回答,该问题提供了此技术的完整描述和代码示例。

在我对If necessary, how to call functions in MainViewViewModel from other ViewModels问题的回答中可以找到您可能感兴趣的其他新增内容。如果您有任何问题,请与我们联系。

答案 1 :(得分:1)

  

我这里有内存泄漏吗?

分配给VM2.WhenP1Changes的lambda捕获this VM1实例(访问VM3属性所需),因此只要视图模型VM2处于活动状态,它就会保持VM1活着。这最终是否是泄漏取决于这些视图模型的生命周期,但其含义实际上与使用事件的第一个示例相同。