我正在尝试使用WinForms首次实现MVP方法。
我试图了解每一层的功能。
在我的程序中,我有一个GUI按钮,单击该按钮会打开一个openfiledialog窗口。
因此,使用MVP,GUI会处理按钮单击事件,然后调用presenter.openfile();。
在presenter.openfile()中,然后应该将该文件的打开委托给模型层,还是由于没有数据或逻辑要处理,它是否应仅对请求采取行动并打开openfile对话窗口?
更新: 我决定提供一笔赏金,因为我觉得我需要进一步的帮助,最好是针对我在下面的特定要点进行调整,以便获得背景信息。
好的,在阅读了MVP之后,我决定实现被动视图。实际上,我将在Winform上具有一堆控件,这些控件将由Presenter处理,然后将任务委派给模型。我的具体观点如下:
当winform加载时,它必须获得树形视图。我是否正确认为该视图因此应调用诸如presenter.gettree()之类的方法,而该方法又将委托给模型,该模型将获取树视图的数据,对其进行创建和配置,然后将其返回给演示者,该演示者又将转到视图,然后将其简单地分配给一个面板?
Winform上的任何数据控件都一样吗,因为我也有datagridview?
我的应用程序具有许多具有相同装配的模型类。它还支持插件体系结构,其中包含需要在启动时加载的插件。视图是否会简单地调用presenter方法,而该方法又会调用加载插件并在视图中显示信息的方法?哪一层将控制插件引用。视图将保留对它们或演示者的引用吗?
我认为视图应该处理有关表示的每件事(从树视图节点颜色到数据网格大小等)是否正确?
我认为这是我最关心的问题,如果我理解这些工作的流程,我会没事的。
这是我对MVP和您的特定问题的谦虚看法。
首先 ,用户可以与之交互或仅被显示的任何东西都是 视图 。这种视图的规律,行为和特征由 界面 描述。可以使用WinForms UI,控制台UI,Web UI甚至根本不使用UI来实现该接口(通常在测试演示者时)-只要遵守其视图接口的规律,具体的实现就无关紧要。
其次 ,视图始终由 演示者 控制。此类演示者的法律,行为和特征也通过 界面 描述。该接口对具体的视图实现不感兴趣,只要它遵守其视图接口的定律即可。
第三 ,由于演示者控制其视图,因此要最大限度地减少依赖关系,让视图完全了解其演示者一无所获。演示者和视图之间有一个约定的合同,该合同由视图界面声明。
第三 的含义是:
对于您的问题,上面的代码看起来有些简化:
interface IConfigurationView { event EventHandler SelectConfigurationFile; void SetConfigurationFile(string fullPath); void Show(); } class ConfigurationView : IConfigurationView { Form form; Button selectConfigurationFileButton; Label fullPathLabel; public event EventHandler SelectConfigurationFile; public ConfigurationView() { // UI initialization. this.selectConfigurationFileButton.Click += delegate { var Handler = this.SelectConfigurationFile; if (Handler != null) { Handler(this, EventArgs.Empty); } }; } public void SetConfigurationFile(string fullPath) { this.fullPathLabel.Text = fullPath; } public void Show() { this.form.ShowDialog(); } } interface IConfigurationPresenter { void ShowView(); } class ConfigurationPresenter : IConfigurationPresenter { Configuration configuration = new Configuration(); IConfigurationView view; public ConfigurationPresenter(IConfigurationView view) { this.view = view; this.view.SelectConfigurationFile += delegate { // The ISelectFilePresenter and ISelectFileView behaviors // are implicit here, but in a WinForms case, a call to // OpenFileDialog wouldn't be too far fetched... var selectFilePresenter = Gimme.The<ISelectFilePresenter>(); selectFilePresenter.ShowView(); this.configuration.FullPath = selectFilePresenter.FullPath; this.view.SetConfigurationFile(this.configuration.FullPath); }; } public void ShowView() { this.view.SetConfigurationFile(this.configuration.FullPath); this.view.Show(); } }
除了上述内容外,我通常还有一个基本IView接口,可以在其中存储Show()和所有所有者视图或我的视图通常受益的视图标题。
IView
Show()
对您的问题:
1. 加载Winform时,必须获取树形视图。 我是否正确认为该视图因此应调用诸如presenter.gettree()之类的方法,而该方法又将委托给模型,该模型将获取树视图的数据,对其进行创建和配置,然后将其返回给演示者,该演示者又将转到视图,然后将其简单地分配给一个面板?
我会打电话IConfigurationView.SetTreeData(...)的IConfigurationPresenter.ShowView(),调用前右IConfigurationView.Show()
IConfigurationView.SetTreeData(...)
IConfigurationPresenter.ShowView()
IConfigurationView.Show()
2. 对于Winform上的任何数据控件,这都一样吗,因为我也有一个datagridview?
是的,我会呼吁IConfigurationView.SetTableData(...)。由视图来格式化提供给它的数据。演示者只是遵循需要表格数据的视图协定。
IConfigurationView.SetTableData(...)
3. 我的应用程序,具有多个具有相同装配的模型类。 它还支持插件体系结构,其中包含需要在启动时加载的插件。视图是否会简单地调用presenter方法,而该方法又会调用加载插件并在视图中显示信息的方法?哪一层将控制插件引用。视图将保留对它们或演示者的引用吗?
如果插件与视图相关,则视图应该了解它们,但演示者不知道。如果它们全部与数据和模型有关,则视图应该与它们无关。
4. 我是否正确认为视图应该处理有关表示的每件事,从树视图节点的颜色到数据网格的大小等?
是。可以认为它是演示者提供描述数据的XML和获取数据并将视图应用于CSS样式表的视图。具体来说,演示者可以呼叫IRoadMapView.SetRoadCondition(RoadCondition.Slippery),然后视图将道路呈现为红色。
IRoadMapView.SetRoadCondition(RoadCondition.Slippery)
那点击节点的数据呢?
5. 如果单击树节点时,是否应该将特定的节点传递给演示者,然后从该演示者中找出需要的数据,然后向模型询问该数据,然后再将其展示给视图?
如果可能的话,我会一口气传递视图中呈现树所需的所有数据。但是,如果某些数据太大而无法从头开始传递,或者它本质上是动态的并且需要模型的“最新快照”(通过演示者),那么我将向event LoadNodeDetailsEventHandler LoadNodeDetails视图界面添加类似的内容,以便演示者可以订阅它,LoadNodeDetailsEventArgs.Node从模型中获取节点的详细信息(可能通过某种形式的ID),以便在事件处理程序委托返回时,视图可以更新其显示的节点详细信息。请注意,如果获取数据可能太慢而无法获得良好的用户体验,则可能需要使用异步模式。
event LoadNodeDetailsEventHandler LoadNodeDetails
LoadNodeDetailsEventArgs.Node