我希望有一个关于MVVM的简单但有人为的问题。
我的MainWindow有1个控件 - ContentControl,它只显示2个视图中的一个。我希望能够通过按钮在2个视图之间切换。问题是,按钮将是每个视图的控件。 EG View1有一个按钮,View2有一个按钮。 UI上只显示1个视图,单击按钮将显示其他视图。但是,为了实现这一点,它将意味着View的ViewModel必须知道MainWindow的ViewModel才能更改View。这似乎不对。
问题可能是我的MainWindow ViewModel。其中一个项目是公共对象View {get; set},这是绑定到MainWindows ContentControl的内容。因此,需要从View的viewmodel更新此属性。
如果View更新了MainWindow的ViewModel,是否会违反MVVM模式?
答案 0 :(得分:3)
我不确定我是否完全理解你的问题,但是在viewmodel之间进行通信的一种好方法是通过EventAggregator或者Messenger模式。 这两个以松散耦合的方式实现pub / sub。
这是MVVMLight Toolkit的Messenger的一个例子 http://dotnet.dzone.com/articles/mvvm-light-whats-messenger
这是Prism的EventAggregator在viemodels之间传播的一个例子 http://rachel53461.wordpress.com/2011/06/05/communication-between-viewmodels-with-mvvm/
希望这会有所帮助..
编辑:好的,我的答案仍然有效。如果你使用上面提到的pub / sub,你会告诉view1
和view2
发送更改视图消息,例如定义一个目标(例如,目标可能是view2
)。然后,您将在MainViewModel
中订阅每条更改视图消息。当更改视图消息到达时。 MainViewModel
会收到通知并执行一个事件,并不一定知道是谁发送了该消息。
请记住,mvvm只是一种不是宗教的模式......只是使用让你前进的东西并在你脑后拥有这种模式=)......
答案 1 :(得分:1)
您的视图模型不应该理想地对视图有任何引用。 If you're doing MVVM then you really need to use an MVVM framework。你所描述的似乎是一个视图模型正在进行另外两个视图模型。
就个人而言,如果只有一个订阅者对该消息感兴趣(在这种情况下是父主视图模型),我就不会使用事件聚合器。如果需要松耦合,可以使用普通的.NET事件并应用标准事件模式。
您的主视图模型将保留对两个子视图模型的引用,并将订阅其启动切换的事件。当在子1上单击该按钮时,它将调用其事件,然后主视图模型将其事件处理程序中的当前视图切换为子2。
使用Caliburn.Micro等MVVM框架非常容易。您的主视图模型将是Conductor
类型,然后您只需更改ActiveItem
。