C# MVVM正确使用该模式

C# MVVM正确使用该模式,c#,mvvm,C#,Mvvm,我只是想知道我做得对不对。我有一个带有viewmodel(MainWindowViewModel)的mainview(mainview)。在主视图中,有一个按钮可调用另一个视图(子视图)。子视图还有一个视图模型(子视图模型)。子视图通过其viewmodel关闭后,我希望从mainviewmodel访问子视图模型中的属性。 从mainviewmodel调用子视图并访问属性的代码如下所示: private void SubViewExecute(object parameter) { Sub

我只是想知道我做得对不对。我有一个带有viewmodel(MainWindowViewModel)的mainview(mainview)。在主视图中,有一个按钮可调用另一个视图(子视图)。子视图还有一个视图模型(子视图模型)。子视图通过其viewmodel关闭后,我希望从mainviewmodel访问子视图模型中的属性。 从mainviewmodel调用子视图并访问属性的代码如下所示:

private void SubViewExecute(object parameter)
{
    SubView sub = new SubView();
    bool? result = sub .ShowDialog();
    if (!result.HasValue || !result.Value) return;
    if (sub.DataContext is SubViewModel)
    {
        SubViewModel subViewModel = (sub.DataContext as SubViewModel);
        string property = subViewModel.Property;
    }
}

我的mvvm模式是正确的,还是有更好的方法来实现我想要的?

现在还不完全清楚您想要的是什么,但这绝对违反了纯粹意义上的mvvm

在本例中,您的
MainViewModel
,需要直接了解视图层(
SubView
),这通常是尽可能避免的

但是,避免这种情况的最佳方法在很大程度上取决于您是否在使用框架(许多框架都有用于将视图与ViewModel匹配以及显示对话框等的工具)、使用哪个框架,以及您是先使用视图还是先使用ViewModel。

对于您的核心问题:“我的mvvm模式是否正确,或者是否有更好的方法来实现我想要的目标?”

不,您没有正确地遵循MVVM的核心原则,并且有更好的方法来实现您的目标(如果我正确理解您的目标)

首先,MVVM需要使所有层都可测试,而不需要了解上面的“层”。“例如,您的应用程序应该能够通过模型在技术上完成它应该做的一切;它应该能够根据需要检索、更新和创建数据——即使这些数据尚未以用户直观的方式呈现

其次,您的应用程序应该能够在技术上通过视图模型完成用户希望它完成的所有操作,但不需要任何类型的UI。因此,您应该能够“查看”数据并执行各种程序功能,如保存

然后,当您将视图放在顶部时,您只需要数据绑定和事件处理,就可以开始了!(大部分)

主要是视图的责任是从ViewModel中正确管理自己的DataContext;将datacontext推送到特定视图上不是ViewModel的工作。另一种方式是,视图访问ViewModel中的方法和属性,以在用户界面中完成用户请求的工作

因此,我将首先翻转您的代码,以便视图控制在任何给定时间哪些视图处于活动状态,并且每个视图都知道自己的数据上下文以及使用它们的方法

(现在,在SO社区责怪我不要说任何关于VM-first方法的话之前——就是这样。你可以尝试VM-first方法,但一开始更难理解,你会想使用一个框架来帮助你,比如Caliburn.Micro或MVVMLite之类的)

因此,对于View First,您要做的是让MainView知道如何使用子视图填充自己。MainView的任务是确保其数据上下文是正确的MainViewModel,因为每个子视图都是在MainView中创建的,所以MainView将确保每个子视图都将正确的子视图模型实例设置为其数据上下文

这在逻辑上应该很容易实现,因为MainViewModel中已经包含了一组子ViewModels(各种类型)


希望这有助于您继续,如果您有更具体的代码问题(带有示例代码),我们可以进一步帮助您。

重要提示:始终记住MVVM是一套指导原则,而不是规则,任何最适合您的都可以,确保代码干净、不违反干性和稳定性。。就我的观点而言,虽然我特别做的是创建一个enum
(对话框、窗口、默认值等)
作为ViewModels的一部分,然后
WindowManager
利用这个值来确定是否应该在新对话框中打开这个特定的ViewModel,等等。啊哈!视图的任务是确定何时打开新对话,而不是查看模型。=)