Xaml 从父视图模型向下传递或获取值到子视图模型?

Xaml 从父视图模型向下传递或获取值到子视图模型?,xaml,mvvm,nested,viewmodel,mvvm-light,Xaml,Mvvm,Nested,Viewmodel,Mvvm Light,我正在使用MVVM轻型框架以及Unity for DI。我有一些嵌套视图,每个视图都绑定到相应的ViewModel。ViewModels通过Laurent Bugnon在MVVM Light中提出的ViewModelLocator思想绑定到每个视图的根控件DataContext。这允许通过静态资源查找ViewModels,并通过依赖项注入框架(在本例中为Unity)控制ViewModels的生存期。它还允许Expression Blend查看有关ViewModels的所有内容以及如何绑定它们 正

我正在使用MVVM轻型框架以及Unity for DI。我有一些嵌套视图,每个视图都绑定到相应的ViewModel。ViewModels通过Laurent Bugnon在MVVM Light中提出的ViewModelLocator思想绑定到每个视图的根控件DataContext。这允许通过静态资源查找ViewModels,并通过依赖项注入框架(在本例中为Unity)控制ViewModels的生存期。它还允许Expression Blend查看有关ViewModels的所有内容以及如何绑定它们

正如我所说的,视图有一个健康的嵌套剂量,但ViewModels并不真正了解彼此。父视图通过静态资源ViewModelLocator(使用Unity控制ViewModel对象的构造和生存期)绑定到其相应的ViewModel。该父视图中包含一个用户控件,该控件是另一个子视图,然后该子视图也会通过ViewModelLocator获取相应的ViewModel。ViewModels彼此之间没有引用,也不知道彼此之间的任何层次结构

下面是ViewModels如何通过消息进行交互的示例。我有一个父视图,它有一个组合框数据绑定到ViewModel中的ObservableCollection。组合框的SelectedItem也绑定(双向)到ViewModel上的属性。当组合框的选择更改时,这将触发其他视图和子视图中的更新。目前,我正在通过MVVM Light中的消息传递系统实现这一点

所以我想知道从一个视图模型到另一个视图模型获取信息的最佳实践是什么?在本例中,我需要传递给子ViewModels的基本上是表示当前登录用户的用户Guid。最上面的父视图(嗯,ViewModel)会知道这些信息,但我不确定如何将其放入子ViewModels中

我可以想到一些可能的方法:

  • 子视图模型是否应询问 的静态资源ViewModelLocator 对同一对象的引用 父视图正在使用并访问 那样吗?好像 查看模型之间的相互关系 房地产不是很干净和干净 不必要地把他们结合在一起

  • 我已经在使用消息通知了 用户选择的子视图 组合框中的一个新项和 相应更新。但是这个物体 要在中选择的类型 ComboBox并不是直接的 与此数据值相关的 子视图需要


    • 我基本上看到了两种方法。对于一般的跨VM通信,事件聚合器模式非常有效

      但是,对于VM的层次结构,使用访问者模式可能更好。通过访问者,您可以获得贯穿层次结构的信息,例如自动为每个子级提供对父VM的引用

      您也可以使用EA实现这一点,但挑战在于在消息的有效负载中传递足够的信息,以便孩子们知道这是他们应该关心的事情

      至于虚拟机定位器,绝对不是!VM定位器的内容对于UI中的绑定来说是非常严格的,它不应该在该上下文之外出现(最好)

      我的0.02美元
      Glenn

      我决定让子ViewModels发布一条请求所需信息的消息,然后让父VM订阅该消息类型和密钥令牌。我不想过度使用这种通信方式,但我认为它将对一些我难以找到方法向下推过视图层次结构的数据有效。到目前为止,大多数数据传递都是对事件的响应,但并不是每一条数据都能以这种方式传递,特别是当数据被获取或事件发生在不同的屏幕上时,甚至在构建和读取新视图以接收数据之前


      我确实在推特上与一些知名人士(格伦·布洛克、约翰·帕帕和罗伯·艾森伯格)进行了交谈。他们提出了一些类似访问者模式的建议,但我不确定,如果没有虚拟机的层次结构,这种方法是否能很好地工作。这可能是因为我的设计基本上是视图优先,而不是视图模型优先。另一个可行的建议是修改ViewModelLocator和依赖项注入的使用,以包括在创建时将数据值传递给子VM的功能。由于VML的静态特性,我在设想它时遇到了一点困难,并决定我提出的消息请求解决方案暂时会更直接、更简单。如果有太多的数据落入这种情况,我可能不得不重新考虑解决方案。

      事实上,我需要从最顶层的ViewModel中获取的不仅仅是经过身份验证的用户id;DatePicker控件中还有一个开始和结束日期值,需要传递给子ViewModels以过滤一些数据。总体上回答得很好,其中一部分接近我选择的解决方案。虽然我没有VM层次结构,但只有视图是嵌套的,然后互补的VM将数据绑定到每个视图。我想我最终得到了类似EA的东西;我会发布一个答案来解释我做了什么。