【问题标题】:Prism: ViewModelLocator creates the view model instance(s) but how can I target it?棱镜: ViewModelLocator 创建视图模型实例,但我如何定位它?
【发布时间】:2017-06-08 03:07:05
【问题描述】:

有没有一种方法可以在打开相应窗口时识别由 prism 的 ViewModelLocator 创建的 ChildViewModel 实例?

我想触发 ChildViewModel 应该根据来自 MasterViewModel 的参数加载它的数据。

在代码中,在MasterViewModel中有一个ICommand,负责通过发布事件请求打开一个新的子窗口,并且有对应的订阅者。

public ICommand OpenNewChildWindow()
{
    Publish(new OpenNewChildWindowPubSubEvent());

    // Maybe I can publish a new PubSubEvent here
    // but how can I target just the recently created ChildViewModel?
}

请注意,MasterViewModel 对 UI 实现一无所知。

订阅者在自定义WindowManager 上调用ShowWindow 方法,该方法基本上解析了与传入的ViewModel 对应的视图(在此实例中为窗口)。

public void ShowWindow(Type viewModelType)
{
   Type view = ResolveView(viewModelType);
   Window w = (Window)Activator.CreateInstance(view);
   w.Show();
}

适当的窗口的xaml

ViewModelLocator.AutoWireViewModel="True"

【问题讨论】:

  • 这就是为什么你永远不应该使用这些“定位器”的东西。它们使您免于花 5 分钟学习 MVVM 基础知识的几乎难以察觉的不适,并谴责您根据对 MVVM 一无所知的人制定的规则进行一生的痛苦。
  • “根据某人制定的规则做 MVVM 一生的痛苦” - 好点

标签: c# wpf prism prism-6 viewmodellocator


【解决方案1】:

选择视图模型优先的导航风格。如果您将(子)视图模型实例(而不是类型)传递给 ShowWindow,则可以使用所需的任何数据创建它。

很可能,您将数据作为OpenNewChildWindowPubSubEvent 的有效负载传递,然后订阅者创建视图模型。或者您立即在命令中创建视图模型并将其作为事件的有效负载传递。

无论如何,不​​要从视图模型类型中解析视图类型只是为了从视图中解析视图模型类型:-)

顺便说一句,ViewModelLocator 很棒并且确实简化了事情,但您不想在这里使用它,因为您不是在一个 shell 中导航,而是在创建新窗口。如果您愿意,您的视图模型将实现 INavigationAware,并将数据作为参数传递给子视图模型 RequestNavigate...

【讨论】:

  • 是的,我想我必须回去自己创建 VM 实例。我认为 PRISM 的 ViewModelLocator 为我省去了 DI 部分的麻烦,我猜我又回到了 ServiceLocator-ish 模式来帮助创建 VM 和注入依赖项。
  • 添加一个接收所有依赖的工厂,使其CreateMyViewModel方法只有真实数据的参数。
猜你喜欢
  • 2021-09-07
  • 2020-10-03
  • 2019-10-18
  • 2017-05-16
  • 2017-03-26
  • 2019-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多