多个视图模型之间的状态共享的具体示例(WPF MVVM)

Joh*_*tta 31 c# data-binding wpf mvvm

我有一个包含许多对象的WPF/Entity Framework(4.0)项目.我想构建应用程序,以便我可以在视图模型中共享对象选择状态.

例如:我们有汽车,司机,乘客和货物类.我们还有CarList,DriverList等的UserControls以及CarEditor,DriverEditor等的编辑器窗口.此外,我们有所有这些的视图模型(CarListViewModel,Dri​​verListViewModel,CargoEditorViewModel等).这一切都构成了一个可停靠的界面,用户可以在其中打开多个对象列表,编辑器和查看器.

我想要的是如何连接多个视图模型的具体代码示例,以便在CarList中选择汽车将使该汽车在CarEditorView中生效,但也可以在上下文有效的任何其他视图中选择(例如如果有过滤谓词,则为DriverByCarView-或仅为DriverList.

基于这个问题,有许多建议和讨论.似乎占主导地位的两种方法是:

  • 3018307:通过提及消息传递子系统来讨论状态共享
  • 1159035:使用封闭的视图模型讨论状态共享

这些方法中的一种比另一种更好吗?

有没有人以书面或小代码项目的形式有这两种方法的具体例子?

我还在学习WPF,所以对于阅读API基础知识的入门点的建议表示赞赏,但查看代码示例是我经常去的地方.

谢谢


如果有人有兴趣,这里有一些其他类似的讨论:

  • 3816961:讨论根据对象类型返回多个视图模型(即遵循特定接口的任意类型的集合)
  • 1928130:讨论将视图模型聚合为其他视图模型的属性是否是个好主意(例如,由面板视图模型组成的MainWindow视图模型)
  • 1120061:基本讨论是否使用每模型视图模型策略或视图模型每视图元素策略.
  • 4244222:讨论在使用嵌套对象层次结构时是否嵌套视图模型.
  • 4429708:直接讨论视图模型之间的共享集合,但不详细说明.
  • 列表项:讨论在单个视图模型中管理多个选择.

Tim*_*oyd 12

实现此目的的典型方法是使用信使发布CarSelected消息,该消息详细说明所选汽车.零个或多个ViewModel可以订阅CarSelected消息.对当前所选汽车感兴趣的ViewModel可以监听该消息,然后采取相应措施.

信使方法提供了一种干净的解耦设计,其中发布者和订阅者彼此之间没有依赖关系,因此可以轻松地独立发展 - 他们只需要了解汽车消息.信使是中介模式的实现.

在Prism中,信使是EventAggregator用于发布和订阅消息的.

更新

除了EventAggregator带来的体系结构优势之外,它还实现了弱事件,以防止未明确取消订阅的订阅者的内存泄漏问题.

有关EventAggregator文档,请参阅以下内容:

http://msdn.microsoft.com/en-us/library/ff649187.aspx

棱镜:

http://compositewpf.codeplex.com/

棱镜示例

public class ViewModel1
{
    private readonly IEventAggregator _eventService;
    private Car _selectedCar;

    public ViewModel1(IEventAggregator eventService)
    {
        _eventService = eventService;
    }

    //Databound property...
    public Car SelectedCar
    {
        set
        {
            _selectedCar = value;

            var msg = new CarSelectedMessage { Car = _selectedCar };

            _eventService.GetEvent<CarSelectedEvent>().Publish(msg);
        }
    }
}

public class ViewModel2
{
    public ViewModel2(IEventAggregator eventService)
    {
        eventService.GetEvent<CarSelectedEvent>().Subscribe(msg =>
        {
            //DoStuff with msg...
        });
    }
}

public class Car {}

public class CarMessage
{
    public Car Car { get; set; }
}

public class CarSelectedEvent : CompositePresentationEvent<CarMessage> {}
Run Code Online (Sandbox Code Playgroud)