Winforms MVP具有多个视图和一个演示者
本文关键字:一个 MVP 视图 Winforms | 更新日期: 2023-09-27 18:28:12
我正试图按照模型视图演示者(MVP)模式在我的应用程序中开发一个项目管理系统。我的问题是,我已经看到了许多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();
}
}
在这种情况下,一个演示者可能有两个视图。不是两个视图。但是继承可以避免代码与视图的重复。