关于如何为数据绑定 windows 表单应用程序实施 MVP 模式的一些指南
Some guidelines on how to implement MVP pattern for a data binding windows forms app
我想构建一个使用数据绑定的 windows 表单应用程序,我假设它是使用绑定源。我将把大型数据表的不同部分加载到 3 个单独的数据网格视图,并且我将适应如下操作:
1) 将整列数据从一个数据网格视图移动到另一个数据网格视图
2) 编辑单元格内的值
3) 过滤数据
4) 将来,还包括获取实时数据,并显示任何新数据。
我的第一种方法(对我来说似乎合乎逻辑)是入口点可能是演示者,然后演示者将创建视图。然而,我正在认真考虑另一种方法,即使用单独的 class 创建演示者、视图和模型。
第一个问题是:在这种特定情况下,这两种方法中的一种可能更好吗?
第二个问题:现在我的过滤是即时的。但是,如果我实现 MVP,那么这意味着过滤操作必须通过 Presenter class,它会更新模型,然后返回到 Presenter,它会更新视图。也许这对用户来说不是一种视觉上吸引人的体验。如果视图直接连接到模型以进行此类操作(受监督的 MVP),会不会更好?
第三:为将弹出的其他用户控件创建演示者是否是正确的方法,但他们将无法直接访问模型,而是必须先通过应用程序的主要演示者?
这就是我用 Winforms 完成 MVP 的方式,并且效果很好,
1) Model - View绑定的数据结构
2)View——所有可视化逻辑的封装
3) Controller - 对View/Model
执行的所有操作的封装
下面是一个例子,
//Model
class Person : INotifyPropertyChanged
{
//Properties with notification
}
//Views
abstract class View
{
//Base class for all views
public abstract void SetDataSource(object source);
protected virtual void Refresh();
public abstract void Show();
}
//Data grid view
class DataGridView : View
{
private Controller _controller = null;
private System.Windows.Forms.DataGrid _grid = new System.Windows.Forms.DataGrid();
public DataGridView(Controller controller)
{
_controller = controller;
}
public override void SetDataSource(object dataSource)
{
_grid.DataSource = dataSource;
}
public override void Show()
{
}
protected override void Refresh
{
_grid.Refresh();
}
}
//Controllers
abstract class Controller
{
//Base controller
public abstract void Init();
public abstract void Show();
public abstract void ViewChanged(object args);//To receive view changes
}
//Person presenter
class PersonGridController : Controller
{
private DataGridView _view = new DataGridView(this);
private BindingList<Person> _persons = new BindingList<Person>();
public override void Init()
{
//Initialize persons
//Optional, start thread/timer to update persons in background
}
public override void Show()
{
_view.SetDataSource(_persons);
_view.Show();
}
public override void ViewChanged(object args)
{
//Based on arguments, perform filter, edit, save, etc.
}
}
这是我过去使用的基本结构。 Controller 和 View 之间存在耦合,我们可以使用依赖注入(使用 Unity 等框架)将其解耦,并将创建 View 的逻辑移到 Controller 之外。我还有一个工作区管理器 class,它在 Window 中托管视图。如果想简单点,View可以继承自Window class.
关于您的问题,
1) 应通过数据源将列从一个网格移动到另一个网格
2 & 3) 可以使用 Controller.ViewChanged() 事件
完成过滤和编辑
4) 可以使用 Controller.Init() 函数进行实时更新,可以生成一个线程以便在后台更新数据源。
我想构建一个使用数据绑定的 windows 表单应用程序,我假设它是使用绑定源。我将把大型数据表的不同部分加载到 3 个单独的数据网格视图,并且我将适应如下操作:
1) 将整列数据从一个数据网格视图移动到另一个数据网格视图
2) 编辑单元格内的值
3) 过滤数据
4) 将来,还包括获取实时数据,并显示任何新数据。
我的第一种方法(对我来说似乎合乎逻辑)是入口点可能是演示者,然后演示者将创建视图。然而,我正在认真考虑另一种方法,即使用单独的 class 创建演示者、视图和模型。
第一个问题是:在这种特定情况下,这两种方法中的一种可能更好吗?
第二个问题:现在我的过滤是即时的。但是,如果我实现 MVP,那么这意味着过滤操作必须通过 Presenter class,它会更新模型,然后返回到 Presenter,它会更新视图。也许这对用户来说不是一种视觉上吸引人的体验。如果视图直接连接到模型以进行此类操作(受监督的 MVP),会不会更好?
第三:为将弹出的其他用户控件创建演示者是否是正确的方法,但他们将无法直接访问模型,而是必须先通过应用程序的主要演示者?
这就是我用 Winforms 完成 MVP 的方式,并且效果很好,
1) Model - View绑定的数据结构
2)View——所有可视化逻辑的封装
3) Controller - 对View/Model
执行的所有操作的封装下面是一个例子,
//Model
class Person : INotifyPropertyChanged
{
//Properties with notification
}
//Views
abstract class View
{
//Base class for all views
public abstract void SetDataSource(object source);
protected virtual void Refresh();
public abstract void Show();
}
//Data grid view
class DataGridView : View
{
private Controller _controller = null;
private System.Windows.Forms.DataGrid _grid = new System.Windows.Forms.DataGrid();
public DataGridView(Controller controller)
{
_controller = controller;
}
public override void SetDataSource(object dataSource)
{
_grid.DataSource = dataSource;
}
public override void Show()
{
}
protected override void Refresh
{
_grid.Refresh();
}
}
//Controllers
abstract class Controller
{
//Base controller
public abstract void Init();
public abstract void Show();
public abstract void ViewChanged(object args);//To receive view changes
}
//Person presenter
class PersonGridController : Controller
{
private DataGridView _view = new DataGridView(this);
private BindingList<Person> _persons = new BindingList<Person>();
public override void Init()
{
//Initialize persons
//Optional, start thread/timer to update persons in background
}
public override void Show()
{
_view.SetDataSource(_persons);
_view.Show();
}
public override void ViewChanged(object args)
{
//Based on arguments, perform filter, edit, save, etc.
}
}
这是我过去使用的基本结构。 Controller 和 View 之间存在耦合,我们可以使用依赖注入(使用 Unity 等框架)将其解耦,并将创建 View 的逻辑移到 Controller 之外。我还有一个工作区管理器 class,它在 Window 中托管视图。如果想简单点,View可以继承自Window class.
关于您的问题,
1) 应通过数据源将列从一个网格移动到另一个网格
2 & 3) 可以使用 Controller.ViewChanged() 事件
完成过滤和编辑4) 可以使用 Controller.Init() 函数进行实时更新,可以生成一个线程以便在后台更新数据源。