【问题标题】:View only properties (eg: IsSelected) and the Model in MVVM仅查看属性(例如:IsSelected)和 MVVM 中的模型
【发布时间】:2013-08-12 02:51:56
【问题描述】:

考虑使用 MVVM 编写的 WPF 应用程序。该应用需要显示员工列表(名字、姓氏、职务),您可以选择多个进行删除。

本例中的模型是“Employee”,它将实现 INotifyPropertyChanged

视图将是“EmployeeListView”,它将实现 XAML 以显示员工集合。

ViewModel 将是“EmployeeListViewModel”,它将公开一个 ObservableCollection,可以绑定到 EmployeeListView

我的问题是:“IsSelected”属性应该放在哪里?

  1. 在模型中?(我不喜欢这个想法,因为模型现在暴露了一个仅由视图需要且与实际域对象无关的属性,而且,这个属性将是没用,如果我以不同的方式实现视图并且不允许一次删除多个员工)。
  2. 在“EmployeeListViewModel”作为单独的 Dictionary 集合中,它会跟踪员工是否被选中? (或者甚至只是一个包含所有选定员工的 HashSet)。我不太喜欢这样,因为视图中的绑定不再是直截了当的。
  3. 实现一个单独的 EmployeeViewModel,它包装 Employee 对象并公开 IsSelected 属性。然后 EmployeeListViewModel 会将其集合公开为 ObservableCollection。我最喜欢这个解决方案,但我一直认为每个视图有一个 ViewModel,在这种情况下,我的视图有 2 个视图模型。 这是与 MVVM 模式的偏差,还是这是实现 MVVM 的典型方式?(参考?)

【问题讨论】:

    标签: wpf design-patterns mvvm model


    【解决方案1】:

    创建一个可重用的 Generic SelectableItem 来包装 EmployeeList 中的每个项目:

    简单示例:

    public class SelectableItem<T>: INotifyPropertyChanged
    {
        public bool IsSelected {get;set;} //PropertyChanged(), etc
    
        public T Value {get;set;}
    }
    

    然后在 ViewModel 中:

    public ObservableCollection<SelectableItem<Employee>> Employees {get;set;}
    

    在视图中:

    <DataTemplate>
       <CheckBox IsChecked="{Binding IsSelected}" Content="{Value.FullName}"/>
    </DataTemplate>
    

    然后您可以通过以下方式检索所有选定的员工:

    var selectedemployees = Employees.Where(x => x.IsSelected).Select(x => x.Value);
    

    【讨论】:

    • 我很喜欢这个解决方案。但是,尽管我确实询问了有关实施 IsSelected 的问题,但我的问题也是关于它的 kosher 是否是 MVVM 以使一个 View 使用多个 ViewModel。另外,SelectableItem 不是 ViewModel,在这种情况下,这与我的解决方案 #3 类似,但只是以更通用的方式实现? (如果我有更多 UI 特定项目要跟踪 - IsChecked、IsSelected 等,而不是所有 UI 都需要跟踪这些不同的属性)
    • View 上有多个虚拟机是完全可以接受的。实际上,您可以认为 View 上的每个控件都是 View 本身。最好的例子是当你有一个 DataGrid 时,每一行都有自己的虚拟机。
    • 如果有一件事我可以回到 5 年前告诉自己,那就永远不要害怕做一个视图模型!
    • 我更喜欢Item 而不是Value,因为Value 可能会与可空类型混淆
    猜你喜欢
    • 2011-01-29
    • 2010-11-17
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 2011-05-07
    • 1970-01-01
    • 2019-08-21
    相关资源
    最近更新 更多