MVVM最佳实践:视图模型之间的通信

时间:2017-10-27 22:49:32

标签: c# wpf mvvm inotifypropertychanged

我的简化程序结构如下所示:

public class Manager
{
    public Item MyItem { get; set; }

    public void Recalculate(){ ... } 
}

public class Item
{
    public string SomeProperty { get; set; }
}

public class ManagerViewModel
{
    public Manager Model { get; set; }

    public ItemViewModel MyItem { get; set; }
}


public class ItemViewModel
{
    public Item Model { get; set; }

    public string SomeProperty
    {
        get => Model.SomeProperty;
        set 
        { 
            Model.SomeProperty = value;
            RaisePropertyChanged("SomeProperty");
        }
    }
}

SomeProperty中更改ItemViewModel后,我希望在管理员内部触发Recalculate()

我:

A)在ManagerViewModel内部有一个PropertyChangedListener,用于监听其MyItem内的属性更改,然后将其模型告诉Recalculate()

B)允许ItemViewModel有权访问Manager,因此它可以手动告诉Manager运行Recalculate()

...

(B)似乎有点反模式......不应该每个ViewModel只关心它自己的模型吗? (A)有它自己的问题 - 我需要使用这种重新计算'结构很多,看起来这些PropertyChangedListeners到处都是凌乱的。我意识到有几种不同的方法来解决这个问题,但我只是想知道什么是最佳实践'在这种情况下。

2 个答案:

答案 0 :(得分:1)

作为confirmed by Ed Plunkett,'选项A'是最好的方法,因为它分离了ViewModel和Models的关注点。

ItemViewModel只关注它自己的模型,它只会通知任何人在听它的属性已被更改。

ManagerViewModel侦听ItemViewModel内的更改,然后在其自己的模型中执行Recalculate()

//Models

public class Manager
{
    public Item MyItem { get; set; }

    public void Recalculate(){ ... } 
}

public class Item
{
    public string SomeProperty { get; set; }
}

//ViewModels

public class ManagerViewModel
{
    public Manager Model { get; set; }

    public ItemViewModel MyItem { get; set; }

    public ManagerViewModel()
    {
        //Listen for property changes inside MyItem
        MyItem.PropertyChanged += ItemPropertyChanged;
    }

    //Whenever a Property gets updated inside MyItem, run Recalculate() inside the Manager Model 
    private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        Model.Recalculate();
    }
}


public class ItemViewModel
{
    public Item Model { get; set; }

    public string SomeProperty
    {
        get => Model.SomeProperty;
        set 
        { 
            Model.SomeProperty = value;
            RaisePropertyChanged("SomeProperty");
        }
    }
}

答案 1 :(得分:0)

通过向他们添加INotifyPropertyChanged使您的模型可观察是没有错的。然后你可以听你想要的模特。在许多项目中,我更喜欢使用静态数据集层,该层从商店发布模型列表,并且这些模型都是可观察的。这意味着它们可以绑定,并且由于存储是相同的源,因此任何ViewModel等都可以绑定到它们并在系统范围内更新。看起来你走在正确的轨道上,所以不要再猜测自己。使事物可观察,对模型来说是彻头彻尾的,这并不坏或被认为是不好的做法。我个人更喜欢它。

相关问题