【问题标题】:Using MvvmLight.Messaging.Messenger to instantiate new View + ViewModel (Window)使用 MvvmLight.Messaging.Messenger 实例化新的 View + ViewModel (Window)
【发布时间】:2020-02-21 13:49:00
【问题描述】:

我有我的MainView 和关联的MainViewViewModel,它们由ViewModelLocator 链接。

MainViewViewModel 内有一个命令应该触发一个新的Window 打开它有它自己的视图和视图模型(NewViewNewViewViewModel)。

在我看到的很多例子中,建议使用 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 对,它们通过 ViewModelLocatorNewView.xml 中的 DataContext="{Binding NewView, Source={StaticResource Locator}}" 设置链接?

【问题讨论】:

  • 为什么 viewmodellocator 是答案的一部分?我问的原因是还有其他选择。例如,为什么不在消息中发送视图模型实例和视图类型?在主窗口订阅。在主窗口中,您可以实例化窗口。将 datacontext 设置为 viewmodel 并显示窗口。
  • "在主窗口中你可以实例化窗口。" - 这是我正在学习的,因为其他所有解决方案似乎都过于复杂,但这并不遵循 MVVM 架构,因为 ViewModel 负责创建视图。
  • 主窗口中的代码将创建视图。但是....模式的整个想法是让事情变得更容易。它本身并不是终点。所以我不会太担心这是否会破坏任何抽象的架构模式。顺便提一句。我建议传递一个视图模型的实例,因为这样您就可以从“调用”视图模型中解决任何依赖关系或传入参数或任何你喜欢的东西。

标签: c# wpf mvvm mvvm-light


【解决方案1】:

使用窗口服务:

MVVM show new window from VM when seperated projects

您可以使用IWindowService 实现注入视图模型,也可以使用静态WindowService 类:

public static class WindowService
{
    public static void OpenWindow()
    {
        NewView view = new NewView();
        view.Show();
    }
}

依赖注入显然更适合在运行时对视图模型进行单元测试和切换IWindowService 的实现。

【讨论】:

  • 我一定遗漏了一些东西,但是 IWindowService 属于哪个命名空间?我找不到它。
  • 你需要自己定义。按照我的答案中的链接...
  • 我确实读过,但我看到的只是这样实现的 WindowService:public class WindowService : IWindowService IWindowService 定义在哪里?
  • @WSC:这只是一个你需要定义的接口:public interface IWindowService { void OpenProfileWindow(AddProfileViewModel vm); }
猜你喜欢
  • 1970-01-01
  • 2015-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多