【问题标题】:Winforms MVP with multiple views and one presenter具有多个视图和一个演示者的 Winforms MVP
【发布时间】:2012-03-19 15:28:17
【问题描述】:

我正在尝试按照 Model View Presenter (MVP) 模式在我的应用程序中开发项目管理系统。我的问题是,我见过很多 MVP 的例子,但我还没有见过一个有一个 Presenter 和多个 View 的例子。例如,当用户打开一个项目时,可以通过树视图、数据网格和图表查看相同的项目数据。我该如何应对?

【问题讨论】:

    标签: c# winforms design-patterns mvp


    【解决方案1】:

    为了使代码解耦和易于维护,我建议您为每个视图设置一个演示者,即使它们看起来非常相似:这样每个视图都有自己的演示逻辑。 如果您需要在多个视图上显示相同的数据,您可以在演示者之间共享视图模型,但我再次建议您为每个演示者使用不同的视图模型(即使它们非常相似)

    【讨论】:

    • 所以你相信即使有重复的代码,这样做会更好。我是否也使用观察者模式来更新所有相关视图?
    • 如果页面完全相同,但您只在每个页面上显示“多一个标签”,您可以创建一个演示者、一个模型和一个视图。演示者将包含用于显示正确 UI 的逻辑。我的是一般答案
    【解决方案2】:

    您的做法是通过将视图放在接口后面来抽象视图,然后将演示器与视图的具体实现联系起来。

    也就是说,我不确定您是否愿意在现实世界中这样做。处理树视图与处理图表之间的差异意味着您最终会在视图界面中过度概括事物并在视图中编写大量杂乱的代码来履行合同。

    我建议将您的演示者与观看者的比例保持在 1:1。如果您希望对同一数据有多个视图,那么您应该在演示者之间共享您的模型,因此您可以以不同的方式显示相同的数据。

    【讨论】:

      【解决方案3】:

      每个视图实例几乎总是有一个演示者实例。

      假设您打开一个 CustomerView 及其 CustomerViewPresenter。这是每个的一个实例。

      您打开另一个 CustomerView 和另一个 CustomerViewPresenter 实例。这是每个的两个实例。

      这并不意味着给定的演示者总是必须使用相同的视图,事实上它不应该。演示者应该与一个视图界面对话。您应该能够将真实视图换成模拟视图进行测试。

      【讨论】:

      • 我有两个视图(除了一个按钮之外几乎相同),我对两个视图使用相同的模型类并为两个视图使用一个演示者,但有时我会因为应用程序崩溃问题演示者中的视图为空。我有几个问题: 1. 对两个视图使用同一个演示者是否很好。 2.如何保护presenter中的view为null。请提供一些细节。
      【解决方案4】:

      这个问题可能很老,但我只想发布我的答案以备将来使用。

      如果您有一个可以在多个视图上使用的视图,那么继承是关键。

      示例:

      using System;
      
      // declaring an interface
      public interface A {
      
          // declare a treeview;
          void treeView();
          // declare a datagrid;
          void datagrid();
          // declare a chart;
          void chart();
      }
      
      // The views of interface A 
      // is inherited into interface B
      public interface B : A {
          // declare a label or string
          string mystring  { get; set; }
      }
      

      C# 允许用户将一个接口继承到另一个接口。当一个类实现继承的接口时,它必须提供接口继承链中定义的所有成员的实现。

      public partial class Form1 : Form, B
      {
          private Presenter presenter;
      
          public Form1()
          {
              InitializeComponent();
          }
      
          public string mystring
          {
              get
              {
                  return textBox1.Text;
              }
              set
              {
                  textBox1.Text = value;
              }
          }
      
          public void treeView()
          {
              presenter = new Presenter(this);
              presenter.GenerateTreeView();
          }
      
          public void datagrid()
          {
              presenter = new Presenter(this);
              presenter.GenerateDatagrid();
          }
      
          public void chart()
          {
              presenter = new Presenter(this);
              presenter.GenerateChart();
          }
      }
      

      您的演示者可能看起来像这样:

      public class Presenter
      {
          public B viewB;
          public DomainLogic model;
      
          public Presenter(B view)
          {
              viewB = view;
          }
      
          public void GenerateTreeView()
          {
              model = new DomainLogic();
              model.CreateTreeView();
          }
      
          public void GenerateDatagrid()
          {
              model = new DomainLogic();
              model.CreateDatagrid();
          }
      
          public void GenerateChart()
          {
              model = new DomainLogic();
              model.CreateChart();
          }
      
          public void GenerateString()
          {
              model = new DomainLogic();
              viewB.mystring = model.createString();
          }
      
      }
      

      在这种情况下,一位演示者可能有 2 个视图。不是字面上的2个视图。但是继承可以避免代码重复到你的视图中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-03
        • 1970-01-01
        • 2017-08-13
        • 2011-02-25
        • 1970-01-01
        • 2020-07-04
        • 1970-01-01
        相关资源
        最近更新 更多