Winforms MVP框架中的多视图和单个Presenter

7

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

4个回答

4
为了使代码解耦和易于维护,建议为每个视图都提供一个Presenter,即使它们看起来非常相似:这样每个视图都将有自己的呈现逻辑。 如果您需要在多个视图上显示相同的数据,可以在Presenter之间共享ViewModel,但是我仍建议您为每个Presenter使用不同的ViewModel(即使它们非常相似)。

那么您认为即使存在代码重复,也最好采用这种方式。我是否还需要使用观察者模式来更新所有相关视图? - Dimitris
如果这些页面完全相同,只是每个页面上多了一个标签,那么你可以创建一个Presenter、一个Model和一个View。Presenter将包含显示正确UI的逻辑。这是一个通用的解决方案。 - Massimiliano Peluso

2
您可以通过将视图放在接口后面来抽象化您的视图,然后使用具体的视图实现与Presenter进行连接。
话虽如此,我不确定您是否真的想在现实世界中这样做。处理树视图与图表之间的差异会导致您在视图接口中过度概括事物并编写大量混乱的代码以履行合同。
我建议保持您的Presenter和View之间的比例为1:1。如果您想要在相同数据上显示多个视图,则应该共享Model,以便在不同的方式下显示相同的数据。

1

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

比如你打开了一个CustomerView,以及它的CustomerViewPresenter。这是每个实例的一个。

然后你打开另一个CustomerView,以及另一个CustomerViewPresenter实例。这是每个实例的两个。

这并不意味着给定的演示者总是必须使用相同的视图,事实上不应该这样。演示者应该与一个视图接口交互。你应该能够为测试交换真实视图和模拟视图。


我有两个视图(除了一个按钮几乎相同),并且我正在为这两个视图使用相同的模型类,并且使用单个Presenter来处理这两个视图,但有时由于视图在Presenter中为空而导致应用程序崩溃问题。我有几个问题:
  1. 是否适合为两个视图使用相同的Presenter。
  2. 如何保护Presenter中的视图不为空。
请提供一些详细信息。
- Sandeep Insan

0
这个问题可能有点老了,但我想发表我的答案以备将来使用。
如果您有一个可以在多个视图上使用的视图,那么继承是关键。
例如:
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();
    }

}

在这种情况下,您可以在一个Presenter中拥有2个视图。并不是字面上的2个视图,而是通过继承可以避免将代码重复到您的视图中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接