我想知道这件事已经有一段时间了。从另一个视图模型打开一个新窗口(view & viewmodel)的最佳实践是什么,如果我们记住打开新窗口的视图模型并不知道该视图的存在(正如它应该知道的)。
谢谢。
发布于 2010-11-24 19:35:48
我更喜欢使用通过ViewModel构造函数插入的操作委托。这也意味着我们可以很容易地在单元测试期间进行验证:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new MainViewModel(() => (new Window()).Show()); // would be actual window
}
}
public class MainViewModel
{
private Action popupAction;
public MainViewModel(Action popupAction)
{
this.popupAction = popupAction;
}
public ICommand PopupCommand { get; set; }
public void PopupCommandAction()
{
popupAction();
}
}
public class SomeUnitTest
{
public void TestVM()
{
var vm = new MainViewModel(() => { });
}
}
发布于 2010-11-24 19:45:17
使用中介模式,例如mvvmlight的messenger类:
http://mvvmlight.codeplex.com/Thread/View.aspx?ThreadId=209338
基本思想是视图模型向它的视图发送一条消息。然后接收视图如下所示:
OnMsgRecived() {
Viewmodel vm = New Viewmodel() - Or use dependency injection to resolve
View v = new View()
v.DataContext = vm
v.Show()
}
这允许发送消息的视图模型显示另一个窗口,而不知道是如何打开的,或者是谁打开的。
发布于 2010-12-02 12:02:22
就我个人而言,我更喜欢在我的ViewModel中引发事件来向视图发出信号,告诉它需要做一些事情,比如打开窗口。我尽量不直接这样做,这样我就不会在我的ViewModel中看到名为OpenWindow的事件,因为在我看来,这似乎违反了视图和ViewModel之间的分离。相反,我可能要做的是让一个属性改变状态,并相应地引发一个PropertyChanged事件,在这个事件中,视图可以监听,然后决定打开一个窗口来响应这个信号。在某些情况下,窗口的打开与ViewModel中的内容完全无关,只是视图的一个功能。在这些情况下,我一点也不害怕将用于打开另一个视图的代码放在视图的代码隐藏部分中。
mediator pattern使得这一点更加松散耦合,并允许应用程序主窗口视图或高度嵌套的视图可以在应用程序内全局监听消息,而无需直接访问ViewModels以附加事件处理程序等。要过滤掉不相关的消息,您可以查看某种消息源值或消息来源的其他指示。对于那些熟悉Windows message的概念以及它在非托管和WinForms开发中的不同控件(Windows)之间如何工作的人来说,这可能是理解系统可以构建在广播消息的中介之上的一种方式。
https://stackoverflow.com/questions/4266223
复制相似问题