Winforms MVP模式与多个视图

4

我最近开发了一个WinForms应用程序,没有遵循任何特定的设计模式。该应用程序具有4个不同的“视图”,每个视图都使用TableLayoutPanel实现。其中一个视图是“主”视图,允许用户选择输入文件,另外3个视图包含DataGridViews,允许用户对从输入文件加载的数据进行操作。

问题在于,我有一个单独的表单,其中包含4个不同的面板,当需要时会隐藏并显示。但这导致我的表单类比我想象的要大得多,因为我有不同的事件和方法,用于在同一类中操作每个面板的数据。因此,我进行了一些研究,并找到了Model-View-Presenter,但我只找到了显示单视图应用程序的示例。

我的问题是,如果我使用MVP,并且每个视图都有自己的接口和Presenter,而视图的具体实现是使用Form完成的,那么切换视图的最佳方式是什么(例如,单击“下一步”)?

我的视图的具体实现应该是一个Form吗?我是否漏掉了什么?我想遵循MVP模式,但如果有更好的替代方案,我也愿意听取建议。


过去我做这个的时候,我会创建每个视图作为实现特定自定义接口的用户控件,例如 IWizardView。然后使用一些代码来选择适当的视图,也许使用一个有状态的 WizardViewFactory 带有 Next()Prev() 方法。这只是一种选择。 - Sam Axe
UserControl 是处理这个的最佳方式。 - Shift 'n Tab
你可以查看这个链接:http://stackoverflow.com/questions/12647473/how-can-i-display-usercontrol-into-a-form - Shift 'n Tab
谢谢!我会使用UserControl实现并跟进我的解决方案。 - j.castillo
1个回答

5

首先,你需要为三个DataGridView表单中的每一个创建一个UserControl。由于您正在使用MVP,因此每个控件都应该继承一个接口。例如:

public interface IDataGridView1
{
    // Properties, Methods, etc...
}

public interface IDataGridView2
{
    // Properties, Methods, etc...
}

public interface IDataGridView3
{
    // Properties, Methods, etc...
}

以下是一个DataGridView1 UserControl的示例,它继承了其接口和Control:

public class DataGridView1 : Control, IDataGridView1
{
    TableLayoutPanel layoutPanel;

    public DataGridView1()
    {
        layoutPanel = new TableLayoutPanel();
        // Set up the layoutPanel.

        // Rest of constructor, define your controls.

        // Add your controls to layoutPanel.

        // Add layoutPanel to this control.
        Controls.Add(layoutPanel);
    }

    // Methods etc...
}

另外两个DataGridView将类似,但具有自己的功能。

然后,您可以为MainView创建一个接口,其中包括三个应包含的DataGridView的属性,以及显示一个DataGridView并隐藏其余部分的方法:

public interface IMainView
{
    IDataGridView1 DataView1 { get; set; }
    IDataGridView2 DataView2 { get; set; }
    IDataGridView3 DataView3 { get; set; }

    void ShowOnlyDataView1();
    void ShowOnlyDataView2();
    void ShowOnlyDataView3();

    // Other methods, properties, etc...
}

主视图类将从 Form 和其自身的接口继承。这里我展示了通过表单构造函数传入的实例化的 DataGridViews:

public class MainView : Form, IMainView
{
    public IDataGridView1 DataView1 { get; set; }
    public IDataGridView2 DataView2 { get; set; }
    public IDataGridView3 DataView3 { get; set; }

    TableLayoutPanel layoutPanel;

    public MainView(IDataGridView1 dataView1, IDataGridView2 dataView2,
                    IDataGridView3 dataView3)
    {
        this.DataView1 = dataView1;
        this.DataView2 = dataView2;
        this.DataView3 = dataView3;

        layoutPanel = new TableLayoutPanel();
        // Define your layout panel here.

        // Add your controls to layoutPanel.

        // Add layoutPanel to the MainView.
        Controls.Add(layoutPanel);

        // Rest of constructor...
    }

    // Hides other views and show DataView1.
    public void ShowOnlyDataView1()
    {
        DataView2.Hide();
        DataView3.Hide();
        DataView1.Show();
    }

    // Hides other views and show DataView2.
    public void ShowOnlyDataView2()
    {
        // Etc...
    }

    // Hides other views and show DataView3.
    public void ShowOnlyDataView3()
    {
       // Etc...
    }

    // Other Methods etc...
}

这里是一个您的主方法的示例。您需要实例化每个DataGridView并将其传递到MainView:

public static void Main(string[] args)
{
    IDataModel dataModel = new DataModel();
    IDataGridView1 dataView1 = new DataGridView1();
    IDataGridView2 dataView2 = new DataGridView2();
    IDataGridView3 dataView3 = new DataGridView3();
    IMainView mainView = new MainView(dataView1, dataView2, dataView3);
    DataGridPresenter1 dataPresenter1 = new DataGridPresenter1(dataView1, dataModel);
    DataGridPresenter2 dataPresenter2 = new DataGridPresenter2(dataView2, dataModel);
    DataGridPresenter3 dataPresenter3 = new DataGridPresenter3(dataView3, dataModel);
    MainPresenter mainPresenter = new MainPresenter(mainView, dataModel);
}

大致意思是这样的。

你的三个DataGridView显示在MainView中,并且所有四个视图都通过自己的Presenter访问。


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