【发布时间】:2020-02-21 13:49:00
【问题描述】:
我有我的MainView 和关联的MainViewViewModel,它们由ViewModelLocator 链接。
在MainViewViewModel 内有一个命令应该触发一个新的Window 打开它有它自己的视图和视图模型(NewView 和NewViewViewModel)。
在我看到的很多例子中,建议使用 Mvvmlight 的 Messenger 来做这样的事情:
public class MainViewViewModel
{
private void OpenNewWindow()
{
Messenger.Default.Send(new NotificationMessage("NewView"));
}
}
然后注册NewViewViewModel并像这样处理消息:
public class NewViewViewModel
{
public NewViewViewModel()
{
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
private void NotificationMessageReceived(NotificationMessage obj)
{
if (obj.Notification == "NewView")
{
NewView view = new NewView();
view.Show();
}
}
}
但是,这不起作用,因为 NewViewViewModel 尚未实例化(因此未向 Messenger 注册)。此外,这不适合 MVVM,因为 NewViewViewModel 负责创建 NewView。
实现一个简单命令的正确方法是实例化并打开一个新的 View 和 ViewModel 对,它们通过 ViewModelLocator 和 NewView.xml 中的 DataContext="{Binding NewView, Source={StaticResource Locator}}" 设置链接?
【问题讨论】:
-
为什么 viewmodellocator 是答案的一部分?我问的原因是还有其他选择。例如,为什么不在消息中发送视图模型实例和视图类型?在主窗口订阅。在主窗口中,您可以实例化窗口。将 datacontext 设置为 viewmodel 并显示窗口。
-
"在主窗口中你可以实例化窗口。" - 这是我正在学习的,因为其他所有解决方案似乎都过于复杂,但这并不遵循 MVVM 架构,因为 ViewModel 负责创建视图。
-
主窗口中的代码将创建视图。但是....模式的整个想法是让事情变得更容易。它本身并不是终点。所以我不会太担心这是否会破坏任何抽象的架构模式。顺便提一句。我建议传递一个视图模型的实例,因为这样您就可以从“调用”视图模型中解决任何依赖关系或传入参数或任何你喜欢的东西。
标签: c# wpf mvvm mvvm-light