C# 正确实现MVVM模式

C# 正确实现MVVM模式,c#,wpf,model-view-controller,mvvm,C#,Wpf,Model View Controller,Mvvm,我试图实现MVVM模式,但遇到了一些麻烦 整个应用程序可以看作是一个向导。您必须在对话框A中选择一个项目才能看到对话框B,这取决于您的选择。对话框C独立于其他选择,但必须执行一些业务逻辑,这取决于前面的选择 我试图实现一个BaseViewModel来保存对这些选择的引用。BaseViewModel具有对真实模型的引用,真实模型从数据库检索数据并将其存储为属性 我看到的第一个问题是BaseViewModel就像模型的“门面”,因为它提供了对视图的模型属性的访问 第二个问题是,我确实以某种方式对几乎

我试图实现MVVM模式,但遇到了一些麻烦

整个应用程序可以看作是一个向导。您必须在对话框A中选择一个项目才能看到对话框B,这取决于您的选择。对话框C独立于其他选择,但必须执行一些业务逻辑,这取决于前面的选择

我试图实现一个BaseViewModel来保存对这些选择的引用。BaseViewModel具有对真实模型的引用,真实模型从数据库检索数据并将其存储为属性

我看到的第一个问题是BaseViewModel就像模型的“门面”,因为它提供了对视图的模型属性的访问

第二个问题是,我确实以某种方式对几乎每个视图使用相同的BaseViewModel(和相同的引用)。在我看来,这是不对的。这就像我在使用一个普通的MVC模式,通过添加一个不必要的(?)视图模型来增加复杂性

另一个问题是,对话框B的ViewModel依赖于对话框A的选择。我是否必须实现一个属性,该属性在访问模型时检索模型的数据元素

你们对这个系统有什么意见吗


谢谢。

< P>我想我会考虑删除你的BaseVIEW模型,并将你的功能分为每个功能模块的VM(1视图:1 VIEW模型)。然后,您可以根据需要使用MVVM Light Messenger之类的工具在每个VM之间传递必要的数据:。

首先让我说,没有绝对意义上的“正确”答案。这完全取决于你如何解决这个问题,取决于你的技能,以及你问的人的意见

也就是说:

  • 我认为你的第一期根本不是。作为模型周围的门面正是
    MVVM
    中的
    VM
    MVC
    中的
    C
    的本意
  • 关于<强>第二个问题< /强>:如果你有一个类似巫师的结构,那么把对话A、B和C看作一个大视图的不同部分是有意义的。在这种情况下,使用一个数据对象来支持它也是有意义的,无论您称它为
    ViewModel
    Controller
    还是其他什么(只要您不直接从UI中访问业务数据)
始终记住,这些模式不是为了宗教地遵循它们,而是为了合理地利用它们来应对现实世界的问题。因此,首先对您的问题(即业务案例)进行建模,然后设计UI,然后才决定数据结构和设计模式


因此,MVVM(或MVC或任何你最后会称之为MVVM的东西)的决定是最后一个…

对于聚会来说可能有点晚了,但是

您应该将业务逻辑与ViewModels分开。ViewModels实际上应该只包含表示逻辑

我要添加一个
IConfigurationService
,它是合适的
ConfigurationService
实现。将其注册为“singleton”(确切名称取决于您的IoC容器术语,即Unity IoC容器中的
ContainerControlled LifetimeManager
),并让您的ViewModels在其构造函数中接受
IConfigurationService

public WizardPage1ViewModel : ViewModel 
{
    private IConfigurationService configService;

    public WizardPage1ViewModel(IConfigurationService configService) 
    {
        this.configService = configService;
    }

    public string InstallationPath 
    {
        get { return this.configService.InstallationPath; }
        set 
        {
            if(path!=value) 
            {
                this.configService.InstallationPath = value;

                OnPropertyChanged("InstallationPath");
            }
        }
    }
}
在最终的ViewModel中,您只需从该服务中读取它。无需发送消息。只有当视图不知道消息/事件的接收者时,才需要消息/事件聚合器


ViewModels实际上应该只关注表示逻辑(从UI获取输入、对按钮做出反应、在视图中显示格式值,即i18n)

我已经考虑过这种方法。在我看来,这导致了重复的代码,因为几乎每个ViewModel都需要几乎相同的数据。如果您的用例足够简单,那么您在问题中描述的方法就没有问题。如果未来的需求引入了更多的复杂性,那么您将尝试在BaseViewModel中填充越来越多的内容。我认为这是一种判断——如果您可能在某个时候扩展功能或重用某些对话框,那么重构为1视图到1视图模型是值得的。如果没有,那么继续做你正在做的事情。我认为把一个向导的不同部分看作一个大视图是一个好主意。非常感谢。