【问题标题】:How should I use ViewModels? [closed]我应该如何使用 ViewModel? [关闭]
【发布时间】:2023-03-19 02:33:01
【问题描述】:

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

在里面我有一个Menu和一个Frame,用来显示一个与SelectedMenuItem相关的页面。

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

功能:

  1. 用户点击任何 MenuItem 并显示与该 MenuItem 关联的页面。
  2. 他会根据自己的需要用数据填充所有的文本框和组合框。
  3. 他将点击保存按钮(请注意,保存按钮位于主窗口,而不是任何页面。)
  4. 步骤 1、2、3 一直持续到用户希望为止。

现在,我的问题是:

  1. 我应该为每页使用一个 ViewModel 吗?
  2. 我应该只使用 1 个 ViewModel 吗?
  3. 使用单一 ViewModel 的优缺点是什么?
  4. 使用多视图模型的优缺点是什么?
  5. 如果你说我应该使用Multiple ViewModels,那么我应该如何在另一个ViewModel中引用一个ViewModel的属性?

请不要说这取决于程序员的想法。我问这些问题是因为我想创建一个小型数据输入应用程序。我希望它是可维护的。另外,我想以最好的方式创建应用程序。

【问题讨论】:

  • 1.我们总是每页做一个视图模型。这样您就不必考虑其他页面类。 5. 我们会创建类并将它们放在一个视图模型中,所以如果你想要两个类中的一个类,你只需将它添加到每个类中,而不是单独的属性
  • 我看不懂 5. 在你的评论中。

标签: c# wpf silverlight mvvm


【解决方案1】:

主要基于意见。

不过,我认为您需要一个 MainViewModel,它有一个 ObservableCollection<PageViewModel>,其中每个都与一个适当的 DataTemplate(包含页面 UI)和一个 ActivePage 属性相关联,其中一个 ContentPresenter' s内容绑定:

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>

WPF 的 Implicit DataTemplate 功能将负责在 ActivePage 更改时呈现适当的 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

【讨论】:

  • 谢谢,好人。你也可以回答第 5 题吗?
  • “这主要是基于意见。”那么也许你应该投票关闭?
  • 感谢您的努力。抱歉,问一个好问题是我的错误。我想我需要对问题 5 进行更多解释。假设我在 MainViewModel 中有一个名为 MyProperty 的属性。现在我想在 PageViewModel1 中获取它的值。我怎样才能得到它?
  • @HighCore 我试过Direct Reference 方法。但 ViewModel2 始终为 null,这是有道理的。如何初始化 ViewModel1 类中定义的 ViewModel2 属性?
【解决方案2】:

在你的位置,我会为每个View 使用DataTemplate,因为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

【讨论】:

    猜你喜欢
    • 2021-05-21
    • 2023-02-24
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多