MVVM:如何处理嵌套的ViewModel之间的交互?

我一直在尝试经常提到的MVVM模式,在某些情况下我很难定义明确的边界。 在我的应用程序中,我有一个对话框,允许我创建到Controller的连接。 对话框有一个ViewModel类,这个类很简单。 但是,该对话框还包含一个附加控件(由ContentTemplateSelector选择),该控件根据所连接的Controller的特定类型而有所不同。 此控件具有自己的ViewModel。

我遇到的问题是,当我按OK键关闭对话框时,我需要实际创建请求的连接,这需要在内部Controller特定的ViewModel类中捕获的信息。 简单地让所有特定于Controller的ViewModel类实现构建连接的公共接口是很诱人的,但是内部ViewModel是否应该真正负责这种构造?

我的一般问题是:ViewModel应该如何与彼此交互,是否有任何普遍接受的设计模式,特别是当’父’VM需要来自’子’VM的帮助以便知道该怎么做?


编辑:

我确实想出了一个比我原先想象的更清洁的设计,但我仍然不确定这是否是“正确”的方式。 我有一些后端服务,允许ContentTemplateSelector查看Controller实例并伪神奇地找到要为连接构建器显示的控件。 让我烦恼的是我的顶级ViewModel必须查看生成的控件的DataContext并将其转换为适当的界面,这似乎是个坏主意(为什么View的DataContext与创建有关?连接?)

我结束了这样的事情(简化):

 public interface IController { IControllerConnectionBuilder CreateConnectionBuilder(); } public interface IControllerConnectionBuilder { ControllerConnection BuildConnection(); } 

我有我的内部ViewModel类实现IControllerConnectionBuilder ,Controller返回内部ViewModel。 然后,顶级ViewModel可视化此IControllerConnectionBuilder (通过伪魔法机制)。 它仍然困扰我一点,这是我的内部ViewModel执行构建,但至少现在我的顶级ViewModel不必知道脏细节(它甚至不知道或不关心可视化控件正在使用视图模型)。

如果有办法进一步清理它,我欢迎其他想法。 我仍然不清楚ViewModel有多少责任“好”。

适用于视图模型之间交互的选项是直接绑定到位于viewmodel类之间的观察者类。

我想你想让你的顶级ViewModel意识到NestedViewModel的存在,从层次结构的角度来看,主视图包含了子视图。

在我看来,你的直觉是正确的,嵌套的ViewModel暴露由顶级用户操作启动的行为感觉不正确。 相反,顶级ViewModel应该为与其关联的视图提供行为。

但我考虑将连接构造的责任转移到ICommand ,并通过顶级ViewModel公开此命令。 然后,主对话框上的OK按钮将绑定到此命令,该命令将委托给顶级ViewModel ,例如,在执行时调用ViewModel.CreateConnection()

然后,嵌套控件的责任纯粹是将数据收集并公开给它的NestedViewModel ,供包含的ViewModel ,理论上它在不同的上下文中更易于重用,需要输入相同的信息(如果有的话) – 让我们说你想重新用它来编辑已经创建的连接。

如果不同类型的NestedViewModel暴露出完全不同的数据集,那么唯一的问题就是如此。

例如,一个将HostNamePort公开为属性,另一个公开UserNamePassword

在这种情况下,您可能需要执行一些基础结构工作,以使您的顶级ViewModel.CreateConnection()仍然以干净的方式工作。 虽然如果你有少量的嵌套控件类型,它可能不值得努力,并且一个简单的NestedViewModel类型检查和NestedViewModel就足够了。

这听起来可行吗?

我最近尝试使用Unity(Microsoft Enterprise库)来使用dependency injection。 当使用完全定义两个视图模型彼此不需要的接口时,这可能是一条路。 MEF将是我所知道的dependency injection的另一种选择。

HTH