0

这个问题是关于如何在考虑到 MVVM 的情况下考虑应用程序设计。我了解 MVVM 的一般概念(ViewModel 不知道 View,Models 表示域对象等......)。我也知道命令以及某些控件如何调用 ViewModel 上的命令。

我想不通的是如何考虑一个真实的应用程序来适应这个模型(而不是简单的文本框/按钮/查询数据库示例)。这里有一些问题:

  • 在主视图中,我有预览部分,它根据用户的操作显示上下文数据(即通过与某些控件交互,显示一些预览部分)。视图是否应该包含 XAML 中所有可能的预览,然后显示/隐藏/更新?ViewModel 是否应该具有由 ViewModel 的内部状态机设置的“public bool ShowPreviewA”和“public bool ShowPreviewB”之类的属性?
  • 当某些控件之间存在复杂的交互时,逻辑应该在哪里。例如,通过防止取消选中,必须选择至少一个必须选中的 3 个复选框。在我看来,一方面它会污染 ViewModel,另一方面也感觉对 View 有一定的“知识”。

这个问题很难正确表达(如果可以的话,我可能会更好地理解 MVVM)。

欢迎任何提示。

编辑:真正的问题是在编写 ViewModel 的功能时如何解决问题。它是自上而下的组合 - 即在 ViewModel 属性中编码每个可能的视图状态 - 和自下而上 - 即每个逻辑相关的控件集从报告“向上”一些逻辑状态(例如有效输入)的子 ViewModel 接收它们的属性?

4

1 回答 1

1

在主视图中,我有预览部分,它根据用户的操作显示上下文数据(即通过与某些控件交互,显示一些预览部分)。视图是否应该包含 XAML 中所有可能的预览,然后显示/隐藏/更新?ViewModel 是否应该具有由 ViewModel 的内部状态机设置的“public bool ShowPreviewA”和“public bool ShowPreviewB”之类的属性?

不,当然不是,如果这些“预览”是完全不同的 UI,具有完全不同的数据,那么使用DataTemplates.

例如:

给定一些类:

public class Person: BusinessEntity //BusinessEntity is just a fictional base class for Model classes
{
    public string LastName {get;set;}
}

public class Product: BusinessEntity
{
    public string ProductName {get;set;
}

假设您的 ViewModel 定义如下:

public class SomeViewModel: ViewModelBase //Same comment as above
{
    public BusinessEntity SelectedEntity {get;set;} //NotifyPropertyChanged() etc
}

您的 XAML 可以这样定义:

<Window ...>
   <Window.Resources>

       <!-- DataTemplate for Person class -->
       <DataTemplate DataType="Person">
           <TextBox Text="{Binding LastName}"/>
       </DataTemplate>

       <!-- DataTemplate for Product class -->
       <DataTemplate DataType="Product">
           <TextBox Text="{Binding ProductName}"/>
       </DataTemplate>
   </Window.Resources>

   <ContentPresenter Content="{Binding SelectedEntity}"/>

</Window>

WPF 将负责根据ViewModel中的属性中放置的对象类型来呈现适当DataTemplate的内部。ContentPresenterSelectedEntity


当某些控件之间存在复杂的交互时,逻辑应该在哪里。例如,通过防止取消选中,必须选择至少一个必须选中的 3 个复选框。在我看来,一方面它会污染 ViewModel,另一方面也感觉对 View 有一定的“知识”。

您可以轻松地继承ObservableCollection<T>以可重用的方式创建此逻辑。然后在您的 ViewModel 中放置一些public SelectableCollection<T> MyItems {get;set;}选择/互斥等由等处理的SelectableCollection位置。

底线:MVVM 是关于可重用性和功能封装的。

于 2013-07-05T19:50:19.710 回答