我应该如何使用ViewModels?

时间:2014-03-20 17:59:52

标签: c# wpf silverlight mvvm

假设我有一个名为MainWindow的窗口。

在里面我有一个菜单和一个框架,用于显示与SelectedMenuItem相关的页面。

假设我有10个页面,分别是Page1,Page2,......,Page10。现在我想在Frame中显示这些页面。所有页面都有一些标准控件,如TextBox,TextBlock,ComboBox等。

功能:

  1. 用户点击任何MenuItem,并向他显示与该MenuItem相关联的页面。
  2. 他将根据需要为所有TextBoxes和ComboBox提供数据。
  3. 他将点击“保存”按钮(请注意,保存按钮位于MainWindow上,而不是任何页面上。)
  4. 步骤1,2,3一直持续到用户希望。
  5. 现在,我的问题是:

    1. 我应该每页使用一个ViewModel吗?
    2. 我应该只使用1个ViewModel吗?
    3. 使用Single ViewModel有哪些优点和缺点?
    4. 使用多个ViewModel有哪些优点和缺点?
    5. 如果您说我应该使用多个ViewModel,那么我应该如何在另一个ViewModel中引用一个ViewModel的属性?
    6. 请不要说这取决于程序员的想法。我问过这些问题,因为我想创建一个小型的数据输入应用程序。我希望它是可维护的。另外,我想尽可能以最佳方式创建应用程序。

2 个答案:

答案 0 :(得分:2)

主要基于意见。

不过,我的意见是,您需要一个MainViewModel,其中ObservableCollection<PageViewModel>每个都与正确的DataTemplate(包含Page UI)和ActivePage相关联ContentPresenter内容绑定到的属性:

public class MainViewModel
{
    ObservableCollection<PageViewModelBase> Pages {get;set;}

    PageViewModelBase ActivePage {get;set;}
}

public class PageViewModelBase
{
   //.. logic common to all pages
}

public class PageViewModel1: PageViewModelBase
{
   //.. logic which belongs to Page 1
}

public class PageViewModel2: PageViewModelBase
{
   //.. logic which belongs to Page 2
}

//And so on...

XAML:

<Window ...>
    <Window.Resources>
       <DataTemplate DataType="{x:Type local:PageViewModel1}">
           <local:Page1/>
       </DataTemplate>

       <DataTemplate DataType="{x:Type local:PageViewModel2}">
           <local:Page2/>
       </DataTemplate>

       <!-- and so on... -->
   </Window.Resources>

   <ContentPresenter Content="{Binding ActivePage}"/>
</Window>

ActivePage发生变化时,WPF的Implicit DataTemplate功能将负责渲染适当的DataTemplate。

修改

有几种方法可以处理ViewModel到ViewModel的通信。

直接参考

ViewModel1包含对ViewModel2的引用并根据需要对其进行操作:

public class ViewModel1
{
    public ViewModel2 ViewModel2 {get;set;}

    void SomeMethod()
    {
        ViewModel2.SomeProperty = "SomeValue";     
        ViewModel2.ExecuteSomeAction(someParameter);
    }
}

EventAggregator / Messenger模式:

请参阅This Answer

答案 1 :(得分:1)

在您的位置,我会为DataTemplate使用View,因为DataTemplate允许创建非常动态的应用。

  

Should I use a ViewModel per Page?

如果每个页面的逻辑彼此非常不同,那么是 - 您需要为每个页面使用单独的View/ViewModel

  

What are the advantages and dis-advantages of using a Multiple ViewModels?

主要优势 - 它的单一责任原则SRP

  

一个班级应该只有一个责任

在我们的情况下,班级 - View/ViewModel。该对象只有一个任务,它独立于其他任务。例如,您有一个打印页面并显示表格的任务。这两个任务都是不相关的,适当地它应该在不同的软件实体中实现。这样做是为了独立地改变每个类的逻辑。

缺点:因为每个页面都必须单独执行View/ViewModel,这可能会耗费一些时间和资源。

  

Should I use only 1 ViewModel?

在这种情况下,将有一个基础ViewModel,它应该包含其所有后代的基本逻辑。

  

What are the advantages and dis-advantages of using a Single ViewModel?

优势:只有一个基地ViewModel只能继承她并补充功能。结论:它更容易使用。

缺点:并非总是而且无处不在,您可以找到合适的基类。如果一个人定义了错误的逻辑,那么在应用程序的进一步开发中会出现问题,因为所有的后代都将继承他。

  

If you say that I should use Multiple ViewModels, then how should I refer to properties of one ViewModel in another ViewModel?

有几种方法,我最喜欢Mediator模式:

  

介体模式定义了一个对象,该对象封装了一组对象的交互方式。由于它可以改变程序的运行行为,因此这种模式被认为是一种行为模式。

Here,您可以看到使用此模式的示例。

还建议您查看MVVM风格的DataTemplate工作示例:

Resolving windows in Structure Map or how to manage multiple windows in WPF MVVM?

Make (create) reusable dynamic Views