如何在多个视图中捕获PropertyChanged事件?

时间:2016-06-22 14:52:11

标签: c# wpf mvvm mvvm-light

我最近开始学习WPF,这让我学习了MVVM和最终的MVVM Light,所以仍然是这三者的首发。我正在构建一个应用程序,其布局类似于链接中的图片 - > Application layout

为了保持良好的代码分离并避免大量文件我决定最好的方法是创建一个主 View ,并在其中创建几个较小的 Views per& #34;区"的UI。根据我在几个教程中阅读的内容,建议每个 View 维护1 ViewModel 。因此,我有一个主视图/ ViewModel ,以及几个同时运行的 View / ViewModels

最后,我有一个模型,可以跟踪我计划在UI中显示的信息。 Model 与可以修改其中数据的外部API进行交互。因此,除了通过用户请求修改数据(例如:按下按钮或定时器)之外,数据也将随着来自API的异步事件而改变。这意味着我需要在 Model ViewModels / Views 之间进行双向通信。

问题:

1。您是否同意每个区域的" 1视图"?每个View的1个ViewModel?

2. 在Main View-Code-Behind中我实例化所有ViewModel,并在每个View中绑定它们,就像我看到的MVVM Light示例中一样:

<UserControl ... DataContext="{Binding Main, Source={StaticResource Locator}}">
<UserControl ... DataContext="{Binding SideBar, Source={StaticResource Locator}}">
<UserControl ... DataContext="{Binding TopBar, Source={StaticResource Locator}}">

这是将几个ViewModel实例化并绑定到相应视图的正确方法吗?

3. 每个ViewModel在其构造函数中传递对Main ViewModel(Main本身除外)的引用,该构造函数是唯一一个引用Model的构造函数。这就是我将几个ViewModel连接到Model的方法。这在概念上是否正确?

4。最初我试图避免使用MVVM Light或其他框架,如果我可以使用RaisePropertyChanged方法做我想做的所有事情。我可能做错了,但是例如,当Model调用RaisePropertyChanged时,我可以在Main ViewModel中捕获该事件,但是它不会传播到ViewModel的其余部分,所以我必须自己做第二次调用RaisePropertyChanged:

public MountainTopViewModel()
{
    _model = new MachineStatusModel();
    _model.PropertyChanged += ModelPropertyChanged;
}


void ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "TestVarModel")
    {
        // do something else if needed
        RaisePropertyChanged("TestVar");
    }
}

我猜这不是正确的方法,或者有更好的方法。那么当模型中的属性发生变化时,如何通知所有视图和视图模型,而不必在不同的地方重新调用该方法?

对不起,我很感激一些帮助。

1 个答案:

答案 0 :(得分:0)

这对我来说似乎是不明智的:

  

模型与可以修改其中数据的外部API交互。因此,除了通过用户请求修改数据(例如:按下按钮或定时器)之外,数据也将随着来自API的异步事件而改变。这意味着我需要在Model和ViewModel / Views之间进行双向通信。

我会让异步API事件驱动视图模型中的更改,模型。然后,为了响应来自View的异步API 的更改,viewmodel执行其通常的操作:更新模型并引发视图响应的事件。视图模型已经扮演该角色,因此请使用您所拥有的角色。您的方案增加了您不需要的复杂性,并且它比您可能意识到的更复杂。你问题中的项目# 4 只是增加复杂性的冰山一角;相信我,它只会从那里变得更加丑陋。不要对自己这样做。你年轻。你有生活的一切。

viewmodel处理另一个viewmodel的PropertyChanged事件或者viewmodel暴露特定属性更改值时触发的特定自定义事件并不罕见。它可能有NameChanged事件或其他什么。但据我所知,我在你的问题中没有看到任何特别需要。

1。是的。

2。如果MVVMLight按照你的方式做事,那就去做吧。 Plunkett的Razor:尽可能符合您正在使用的框架的实践。由于许多原因,一致性在编程中是很好的,如果您遵循“规则”,您通常会找到框架会在那里等着帮助你,而不是在每一步都与你作战。这不是自然法则,但它是一个非常可靠的经验法则。

3。这在概念上有点摇摇欲坠。理想情况下,我们尝试编写不依赖于“父”视图模型的视图模型。您的Library视图模型必须知道Book视图模型是什么,因为它包含它们的集合,但如果Book视图模型不依赖于{Library视图模型,它通常会更有用。 1}}。想象一下,在Wheel上编写一个Car,它具有各种依赖关系,然后必须实现Bicycle。您是否Bicycle Alternator,还是创建了假人Car?像你那样的时候,你开始想要搬到佛蒙特州的公社,用木头做有用的物品。

我可能会为每个viewmodel创建一个模型类型,并为所有viewmodel提供对其构造函数中自己的模型的引用。模型可能与视图模型具有相同的父子关系。如果你的模型是实体框架而不是"POCO" classes,那么,是的,每个人或其他什么模型。但是,请直接将它交给他们。