在 wpf 中,我如何从其他 ViewModel 引用 MainWindowViewModel?

Posted

技术标签:

【中文标题】在 wpf 中,我如何从其他 ViewModel 引用 MainWindowViewModel?【英文标题】:In wpf how can i reference MainWindowViewModel from other ViewModels? 【发布时间】:2022-01-07 23:03:57 【问题描述】:

我正在为 Windows 开发一个 wpf/xaml 应用程序。我想使用材料设计框架,我的应用程序基于示例应用程序中的代码松散地建立在此处:http://materialdesigninxaml.net/我的 C#/xaml 知识还可以,但非常生疏。

在此实现中,有一个 MainWindow.xaml 视图链接到 MainWindowViewModel,其中 MainWindowViewModel 处理来自模型和表示逻辑的数据转换。

我的问题是关于用于在 MainWindow.xaml 中查看的“页面”的最佳设计理念 - 我有一个可以在“页面”中导航的应用程序。所以主窗口在ObservableCollection 中有一个潜在页面的存储,并显示导航按钮。单击按钮转到ObservableCollection 中的下一页。 我的问题是关于 pageViewModel 如何与 MainWindowViewModel 交互。例如,用户可能单击 pageView 上的按钮以导致命令移动到另一个页面 - 使用此框架执行此操作需要在 MainWindowViewModel 上执行 ICommand。

到目前为止,我所做的是让 MainWindowViewModel 创建其他 pageViewModel。在实例化时,pageViewModels 保存对 MainWindowViewModel 的引用,该引用可以在 MainWindowViewModel 上进行编码,以便在需要时执行。这似乎可行,但我不禁想到会有一个更优化的解决方案。

我一直在研究关于 SO 的类似问题 - 我需要查看 IEventAggregator 吗?

【问题讨论】:

将主视图模型引用传递给子视图模型是一种合法的方法。你只是征求意见? IMO 导航按钮不应该在页面上,而是在主视图的某个地方。 你也可以使用一些事件总线实现fx. i'm using Catel MVVM framework so I'm using IMessageMediator @celemens 谢谢 - 只是想要一些经验 - 我正在看一些关于 PRISM 库的教程,它们似乎简化了 ViewModel 之间的命令和消息传递。我喜欢消息传递而不是继承引用的想法,因为它解耦了事物。对于按钮示例,我正在考虑登录页面 - 登录后您需要导航到其他地方。 【参考方案1】:

一种可能的解决方案是使用像 caliburn micro 这样的 UI 框架。该框架会自动将 View 与相应的 ViewModel 连接起来。还有一个所谓的conductor。指挥者允许在一个主页面中使用多个页面和它自己的视图和视图模型。它还提供激活和停用行为等等。愿它有所帮助。

【讨论】:

【参考方案2】:

到目前为止,我所做的是让 MainWindowViewModel 创建其他 pageViewModel。在实例化时,pageViewModels 保存对 MainWindowViewModel 的引用,该引用可以在 MainWindowViewModel 上进行编码,以便在需要时执行。

这是一种方法。它的问题在于它在视图模型类之间创建了紧密耦合。

一种更好且通用的方法是使用事件聚合器或信使在视图模型之间进行通信。这消除了紧密耦合,因为“事件”或“消息”的订阅者只观察事件聚合器而不是发布者,并且发布者只知道事件聚合器而不知道订阅者。

有关此概念的更多信息,请参阅this 博客文章。

【讨论】:

以上是关于在 wpf 中,我如何从其他 ViewModel 引用 MainWindowViewModel?的主要内容,如果未能解决你的问题,请参考以下文章

Caliburn.Micro-如何从继承的ViewModel在WPF视图中显示多个项目:Conductor 。Collection.AllActive

WPF 中的 MVVM - 如何提醒 ViewModel 模型中的变化......或者我应该吗?

如何从 viewmodel 访问用户控件上的命令

WPF(MVVM):从 Viewmodel 关闭视图?

如何从 ViewModel 更改样式属性?

如何在 viewmodel 中访问 mvvm 模型中的控件?