C# MVVM中各层的角色

C# MVVM中各层的角色,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我知道在MVVM中,我们希望通过数据绑定将用户输入从视图传播到视图模型,并将视图模型中反映的视图状态提供给模型,在模型中我们编写业务逻辑代码,并通过事件将结果更新给用户。 但是,这是否意味着视图中的每个更改都必须在xaml.cs文件之外进行 以WPF应用程序为例: 如果我们想写一个算法来解决这个难题,我们将把代码放在模型中 但是,假设我们希望在用户单击向下键后更新网格。 是否应该在视图中检查这种移动是否可行,重新绘制棋盘或给玩家任何反馈(如果移动合法或否)?(xaml.cs文件) 更一般地说,是

我知道在MVVM中,我们希望通过数据绑定将用户输入从视图传播到视图模型,并将视图模型中反映的视图状态提供给模型,在模型中我们编写业务逻辑代码,并通过事件将结果更新给用户。
但是,这是否意味着视图中的每个更改都必须在xaml.cs文件之外进行
以WPF应用程序为例:

如果我们想写一个算法来解决这个难题,我们将把代码放在模型中
但是,假设我们希望在用户单击向下键后更新网格。 是否应该在视图中检查这种移动是否可行,重新绘制棋盘或给玩家任何反馈(如果移动合法或否)?(xaml.cs文件)

更一般地说,是否有“经验法则”来决定在哪里处理什么?

MVVM层的快速回顾(或“经验法则”):

  • 模型:仅包含视图模型使用的数据。作为一个示例,将来自数据库的业务对象视为“模型”。
  • 视图:用户与视图模型之间的连接。可以对同一视图模型使用多个视图。如果视图模型发生更改和更新,则视图应显示更改
  • 视图模型:包含视图和模型之间的“业务逻辑”。因此,命令、可能的操作和算法都存储在这里。视图模型决定了什么是可能的,什么不是
层之间的通信需要(这是MVVM所必需的部分)是可互换的,这意味着视图模型可以与不同的兼容视图一起使用,并且模型可以由不同的兼容视图模型使用。为了减少多个层之间的依赖关系:层之间不应该直接通信。我们使用命令、事件和直接绑定

但是,这是否意味着视图中的每个更改都必须在xaml.cs文件之外进行?[…]但是,假设我们希望在用户单击向下键后更新网格。是否应该在视图中检查这种移动是否可行,重新绘制棋盘或给玩家任何反馈(如果移动合法或否)?(xaml.cs文件)

不可以。视图模型应该明确地告诉视图什么是可能的,什么不是。视图显示该操作是否可行:它不会决定是否可行。这样的决策在业务逻辑中,在视图模型中也是如此

作为一条思路,我们来看看关于可互换观点的说法。如果您将视图
foo
切换到另一个视图
bar
以显示您的谜题,并且您确实在视图中放置了关于“什么是可能的”的决策,那么您必须在新视图
bar
中重写决策树/算法,从而复制代码/逻辑

当决策更高层时,视图反映视图模型告诉他的内容。如果视图模型希望视图“刷新”或告诉用户“嘿,这是非法移动”,则视图模型将通过和事件来执行此操作。收到此类事件后,视图可以决定如何处理它:

  • 显示有关非法移动的错误消息
  • 显示移动非法的工具提示
  • 闪烁并用嘟嘟声摇动窗口,表明该移动是非法的
  • 更多的实现
我希望我能尽可能彻底地回答你的问题。

我的10美分:

如果说我的经验教会了我什么,那就是几乎不可能用相同的、通用的解决方案来解决所有问题

在MVVM的例子中,我学到了一些东西(艰难的过程):

  • 视图模型很容易退化为God类(即,纯视图相关逻辑+一些业务逻辑+等等的混合)
  • 根据应用层的不同,有时逻辑在视图模型上工作是有意义的;其他时候,逻辑更好地处理模型
  • 无论我/你/任何人认为某些类/逻辑应该去哪一层,都很可能随着开发的进展而改变
  • 相反,我的方法通常是:

  • 预备
    • 模型(用于序列化,逻辑很少)
    • 视图模型(具有视图的属性更改绑定)和
    • 视图(薄层,几乎直接绑定到视图模型)
  • 在视图模型中编写大部分应用程序逻辑。
    • 这里更容易有逻辑,因此视图绑定可以工作
    • 这是视图模型层膨胀的阶段
  • 当应用程序最终运行时,开始重构

  • 对于富客户机应用程序,我发现我的模型类几乎完全是数据
  • 视图模型很可能被重构为两层:MVM(模型视图模型)和VVM(视图模型)

    • MVM:这是常见的、与业务相关的逻辑/对象所在的位置
    • MVM对象包含任何视图都可以绑定到的真正通用属性
    • VVM:这几乎是WPF视图的1对1复制
    • 这些对象通常不会在其自身视图之外共享
    • MVM和VVM的分离有助于防止单个视图模型类满足任何视图的需求(即整组
      Is(选中|选中|等)
      *命令
      ,它们只能由一个视图专用)
    • (对一些人来说,VVM逻辑可能是观点的一部分。但对我来说,我经常发现自己最终希望当初为了测试而将它们分开。所以现在我这样做了。)
  • 随着应用程序的发展,属性/方法可以从MVM推送到VVM,反之亦然

    • 应用程序的层次结构几乎从来都不是真正静态的
    • 即使您构建了尽可能最好的应用程序版本,客户机也只需要更多