我有一段时间一直在考虑这个问题...如果我们记住打开新窗口的视图模型不知道该视图的存在(如此应该),那么从另一个视图模型中打开新窗口(视图和视图模型)最佳实践是什么?
谢谢。
谢谢。
我更喜欢使用通过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(() => { });
}
}
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()
}
我个人更喜欢在我的ViewModel中引发事件,以向视图发出信号,告诉它需要执行某些操作,比如打开一个窗口。不过,我尽量不直接这样做,因为我认为在ViewModel中看到像OpenWindow这样的事件似乎违反了View和ViewModel之间的分离。相反,我可能会有一个属性来改变状态,并相应地引发PropertyChanged事件,视图可以侦听此事件,然后决定是否响应此信号打开一个窗口。在某些情况下,打开窗口与ViewModel中的某些内容无关,仅是View的功能。在这些情况下,我毫不害怕将打开另一个视图的代码放置在View的代码后台部分。
中介者模式使得系统更加松散耦合,同时也允许主应用程序窗口视图或高度嵌套的视图在没有直接访问ViewModels的情况下全局监听应用程序中的消息,以便附加事件处理程序等。为了过滤掉不相关的消息,您可以查看某种消息源值或其他指示消息来源的指示。对于那些熟悉Windows消息及其在未管理和WinForms开发中如何工作的人来说,可能是理解基于广播消息的中介者构建系统的一种方式。
我赞同采用类似中介者的方法,但是OnMsgReceived显然是在视图的代码后台处理的,有没有好的方法可以避免这种情况?