我已经开始使用MVVMC(也称为MVCVM或MVVM +),它采用MVVM模式并在视图,视图模型和模型之间添加一个控制器。控制器负责调用应用程序API以检索模型,然后将模型转换为视图模型,然后将模型绑定到其关联视图。这样,ViewModel仍然只承担一项责任;向视图提供数据。但是,我遇到了这种方法的一些问题。
我有一个 MainWindowViewModel ,它为 MainWindowView 提供数据。还创建了 MainWindowController 来驱动此交互。问题是 MainWindowView 包含许多其他视图(例如 ItemsListView 的多个实例),并且这些视图中包含更多视图。
最初,我将所有必需的视图模型添加到 MainWindowViewModel 中,以便每个子视图都可以绑定到其父视图模型的属性。基本上,主窗口的所有视图数据都保存在此视图模型的单个实例中。通过这种方法,我将需要多个控制器来驱动所有这些交互。每个人还应该根据自己的逻辑实例化视图模型。这是否意味着 MainController 应该实例化并保持对所有其他控制器的引用,它将用于填充主视图模型的内部视图模型?这不会让控制器太拥挤吗?
另一种方法是对窗口内的所有视图使用单个控制器,但这似乎违反了单一责任原则。
在WPF中以MVVMC模式实现控制器的正确方法是什么?
答案 0 :(得分:1)
我认为所有这些内部视图都是动态的,因为您使用了“交互”一词。所以我认为最好为每个视图配备不同的控制器。
我最近开发了一个WPF MVVMC框架。我会告诉你我如何在框架中处理你的问题类型。
在视图MainWindow.xaml中:
<Window>
<mvmmc:Region ControllerID="View1"/><!-- View 1 -->
<mvmmc:Region ControllerID="View2"/><!-- View 2 -->
<mvmmc:Region ControllerID="View3"/><!-- View 3 -->
</Window>
Region是一个特殊的Control,具有动态内容,由Controller控制。当加载时,将根据 ControllerID 创建控制器实例,控制器将确保创建View和ViewModel作为Region的内容。
现在,假设在 MainWindowViewModel 中,您想要更改 View1 和 View2 的内容。代码是:
void ChangeContentOfView1AndView2()
{
_navigationService.GetController("View1").Navigate("SomeAction");
//Here's another way to find a controller and navigate
_navigationService.GetController<View2Controller>.OtherAction();
}
因此 MainWindowViewModel 可以找到控制器,该控制器控制代码中的某个 Region 并要求其导航。导航的逻辑,如填充特定的ViewModel属于特定的控制器。不要 MainWindowViewModel 。
在这个简单的解决方案中,没有 MainWindowCotroller ,因为MainWindow的视图是静态的。不需要控制器。 ViewModel,根据按下按钮或任何事件,找到区域的相关控制器并调用它。
在View1Controller中:
public class View1Controller : Controller
{
public void SomeAction()
{
ExecuteNavigation();
}
}
ExecuteNavigation 会找到名为“SomeActionView”的Control和名为“SomeActionViewModel”的ViewModel,并会设置相关的区域< / strong>内容为 SomeActionView 。其DataContext为 SomeActionViewModel 。
如果您正在寻找完整的WPF解决方案,请查看我在此使用的MVVMC框架。导航有点类似于Asp.NET Core。
包含文档的博文: http://michaelscodingspot.com/2017/02/15/wpf-page-navigation-like-mvc-part-2-mvvmc-framework/