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