【问题标题】:What should go in each MVVM triad?每个 MVVM 三元组应该包含什么?
【发布时间】:2010-05-15 10:55:51
【问题描述】:

好的,假设我正在创建一个程序,该程序将在屏幕左侧的 ListBox 中列出用户联系人。当用户单击联系人时,会在窗口的主要部分显示一堆消息或任何内容。

现在我的问题是:MVVM 三元组应该是什么样子?我有两个模型:联系人和消息。 Contact 模型包含一个 Message 模型列表。

每个 ViewModel 对象都将包含一个对应的模型,对吧?

那么视图呢?我有一个“MainView”,它是主窗口,其中包含菜单、工具栏等内容。我是否将 ListBox 放在 MainView 中?我的困惑是把什么放在哪里;例如,ContactView 应该包含什么?只是一个联系人实例?因此,该单个联系人的 DataTemplate、ControlTemplate、上下文菜单、样式等,然后在 MainView 中有一个它们的 ListBox ...?

谢谢。

【问题讨论】:

    标签: c# .net wpf user-interface design-patterns


    【解决方案1】:

    MVVM 模式的核心是模型,它是数据的结构。所以你有联系模型和消息模型,它们是相关的并且设置得很好。现在你想设计你的界面。 UI 包含一个窗口(MainView)。所以你需要一个 ViewModel。那么 ViewModel 是由什么组成的呢?

    让我们假设您只想在 MainView 中显示一个联系人,而不是一个集合。现在,您的 MainViewModel 可以只引用要公开到视图中的联系人属性。

    Contact c = /*Retrieve a contact from db*/;
    
    ContactName = c.Name;  //Create these two properties
    ContactPhone = c.Phone; //Assuming only these two properties are required by your view
    

    现在您可以像这样将这些属性绑定到您的 MainView

    <Textbox Text={Binding ContactName} /> <!-- Assuming the DataContext is assigned -->
    <Textbox Text={Binding ContactPhone} />
    

    但是我们必须在 MainView 中显示一个集合。因此,我们将单个列表项定义为一个新视图。我们还需要一个 ContactName 和 ContactPhone 的列表。因此,我们将这两个属性包装到一个类中并列出它。这个类被称为 ViewModel。

    (这里你还要添加 Messages 属性)

    因此,各个视图都有自己的视图模型。现在我们将这些视图集成到我们的 MainView 中。

    现在 MainViewModel 应该包含什么?

    • ContactViewModel 列表 - ContactList
    • 选定的 ContactViewModel - SelectedContact
    • MessageViewModel 列表 - SelectedContactMessageList

    这些是如何连接的?

    • ContactList - 绑定到 Contact ListView
    • SelectedContactMessageList - 绑定到消息列表视图
    • SelectedContact - 绑定到联系人 ListView 的 SelectedItem。 setter 应该像这样根据 Selection 修改 SelectedContactMessageList
    SelectedContactMessageList.Clear();
    foreach (Message message in SelectedContact.Messages)
    {
        SelectedContactMessageList.Add(new MessageViewModel(message))
    }// converting the resulting models from SelectedContact.Messages to viewmodels
    

    就是这样。这就是我对 MVVM 的理解。

    关于重点,

    每个 ViewModel 对象都将包含一个对应的模型,对吧?

    不!相反,每个 View 都映射到单个 ViewModel

    为您的应用程序中的每个视图创建一个 ViewModel,并在您的 ViewModel 中仅包含您的视图所需的那些属性。

    【讨论】:

    • 如果我想编辑数据怎么办?还是将数据保存回数据库/硬盘?
    • 每当您在视图中编辑数据时,由于它绑定到视图模型,它会自动将更改传播到模型。因此,您可以将相应的模型保存到您的数据库中。对了,你用的是Linq to Sql吗?
    【解决方案2】:

    我认为 ViewModel 还没有明确的定义,但这就是我的看法...

    视图模型不应该有“子”视图模型,它们不是数据关系和层次结构。 Viewmodel 表示单个视图,并包含该视图的模型/数据。相比之下,视图由用户控件组成,每个控件都可以有自己的 Viewmodel,DataContext 与父视图保持相同。

    换句话说,层次结构是可视的,而不是数据驱动的。

    【讨论】:

      【解决方案3】:

      每个 ViewModel 对象都将包含一个对应的模型,对吧?

      不,如果您查看包含联系人列表和具有消息列表的活动联系人,您查看模型可能包含联系人模型对象的集合和活动联系人视图模型。后者可能包含该联系人的消息模型对象集合。

      根据您的观点,您可以将列表框绑定到MainViewModel.Contacts,并将列表框中的选定项绑定到MainViewModel.SelectedContact。然后可以将消息列表绑定到MainViewModel.SelectedContact.Messages。

      【讨论】:

      • 所以:MainViewModel 有一个所有 ContactViewModel 的列表和一个活动的 ContactViewModel。然后 ContactViewModel 包含一个 MessageModel 列表?我将如何让 MessageViewModel 适应这一切?
      • 如果您有单独的邮件视图,您只需要MessageViewModel。这可以是嵌入式控件,也可以是单独的视图,如对话框。一般来说,每个视图都有一个视图模型。
      猜你喜欢
      • 2011-08-18
      • 2018-01-16
      • 2015-06-15
      • 2012-05-26
      • 2018-08-13
      • 2015-09-13
      • 1970-01-01
      • 2019-08-24
      • 1970-01-01
      相关资源
      最近更新 更多