Winforms MVP具有多个视图和一个演示者

本文关键字:一个 MVP 视图 Winforms | 更新日期: 2023-09-27 18:28:12

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

Winforms MVP具有多个视图和一个演示者

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

实现这一点的方法是通过将视图放在接口后面来抽象视图,然后将演示者与视图的具体实现联系起来。

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

我建议将演示者与视图的比例保持在1:1。如果你想要对同一数据进行多个视图,那么你应该在演示者之间共享你的模型,这样你就可以用不同的方式显示相同的数据。

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

假设您打开了一个CustomerView及其CustomerViewPresenter。这是每种情况的一个例子。

您打开了另一个CustomerView和另一个CustomerViewPresenter实例。这是每种情况的两个例子。

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

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

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

示例:

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();
    }
}

在这种情况下,一个演示者可能有两个视图。不是两个视图。但是继承可以避免代码与视图的重复。