C# 将视图模型属性分组到不同的类别是一种好的做法吗?

C# 将视图模型属性分组到不同的类别是一种好的做法吗?,c#,wpf,design-patterns,mvvm,software-design,C#,Wpf,Design Patterns,Mvvm,Software Design,我正在使用MVVM模式进行一个WPF项目,我想知道是否可以通过将ViewModel的公开属性抽象到单独的类中来改进ViewModel的内部结构 vm通常在同一个类中包含大量属性:一些用于检索用户输入,一些用于公开命令,其他用于公开模型,可能还有一些用于视图模型自身业务逻辑的其他属性。更不用说,这些属性通常具有set和get实体,从而为包增加了一些容量。在VM类中,这可能会很快变得混乱,在那里找到自己的方法可能会变得很有挑战性 作为解决这个问题的一种方法,我正在与我的团队探讨将虚拟机中的属性分为不

我正在使用MVVM模式进行一个WPF项目,我想知道是否可以通过将ViewModel的公开属性抽象到单独的类中来改进ViewModel的内部结构

vm通常在同一个类中包含大量属性:一些用于检索用户输入,一些用于公开命令,其他用于公开模型,可能还有一些用于视图模型自身业务逻辑的其他属性。更不用说,这些属性通常具有set和get实体,从而为包增加了一些容量。在VM类中,这可能会很快变得混乱,在那里找到自己的方法可能会变得很有挑战性

作为解决这个问题的一种方法,我正在与我的团队探讨将虚拟机中的属性分为不同类别的想法。作为第一种方法,我选择这样对他们进行分组:

查看数据用户输入命令,每个命令都由自己的类表示。然后我在VM类中将它们作为属性引用

我的意图是,这些类将仅充当占位符,以释放VM中的膨胀并保持其干净,并且只关注用于处理用户事件的交互逻辑

这是一个简单的重构,但我有以下优点:

  • 更干净、可读的虚拟机
  • 更容易从XAML绑定,因为您知道入口点是/应该是什么
让我详细说明后一个:如果我想将文本框绑定到VM的属性,我知道绑定表达式应该以
Userinput.MyVMProperty
开头。如果需要显示VM中的值,我知道绑定的入口点将是
ViewData.MyOtherVMProperty
。绑定intellisense也会变得更好,因为当您知道您的入口点时 建议清单将更小,更集中。这也是另一种方式:当读取XAML控件时,任何以UserInput开头的绑定都必然意味着它是一个应该将数据发送回VM的控件

我能找到的唯一缺点是,这将需要为每个VM创建额外的类,但我相信这是为您获得的好处付出的公平代价

请注意,我建议的分组可能不是最好的,但我不介意任何其他分组,只要它解决了大型VM的问题

那么,有没有人尝试过类似的模式?你认为这是个好主意/做法吗?我还可以使用哪些其他良好实践来改进我的虚拟机


奖金问题:我的团队中的一个开发人员似乎同意这个想法,建议去额外的一英里,并考虑分组类作为VM依赖性,他们需要注入到虚拟机内部。您对此有何看法?

因此,对于每个
ViewModel
,您需要为每个组创建自己的内部类。您不能使用
接口
,因为
视图模型
具有不同的属性和命令

然后,您是否考虑到每个“groupclass”必须“了解”其他组,以便
ViewModel
正常工作。 在我看来,
应该是可靠的逻辑结构,具有最小的外部依赖性

基于您试图实现的优点,我可以建议另一种方法,而不改变ViewModel类的结构

可读性部分可以通过
#区域
实现。 或者使用
Partial class
分隔不同文件中的不同组, 同时将它们保存在一个逻辑结构中

Intellisense
可以通过命名便利性来改进—根据组属性使用前缀。例如
UserInputMyName
ViewDataFullName
CommandDelete

有趣的一个问题是,您将如何处理既为-
UserInput
又为
ViewData
的属性?假设有一个文本框应该显示用户名-它可以编辑和查看,在这两种情况下,您的视图都在文本框中显示用户名。因此,在这种情况下,
UserName
可以同时被视为
UserInput
bcuz,它可以被更改,
ViewData
bcuz您可以使用此属性在表单上显示用户名。那么你打算如何处理这种情况呢?@Michael:我可以确定的一条规则是ViewData应该只包含仅用于显示的属性。从视图到VM的任何其他内容都可以被视为用户输入,即使它也用于显示。我对其他类型的分组持开放态度,例如将UserInputs和ViewData分组在同一个组中。如果一个组需要了解另一个组,则可以在VM中定义知识,因为它可以访问所有组。探索分部类似乎是个好主意,除了view codebehind类之外,我很少使用它们。我担心将组放在自己的类中会使ViewModel过于复杂,无法维护