Model-View-Presenter in WinForms

I am trying to implement the MVP method for the first time using WinForms.

I am trying to understand the function of each layer.

In my program, I have a GUI button that, when clicked, opens the openfiledialog window.

So, using MVP, the GUI handles the button click event, and then calls presenter.openfile ();

Inside presenter.openfile (), to then delegate the opening of this file at the model level or as there is no data or logic to process, should it just act on request and open the openfiledialog window?

Update: I decided to offer generosity because I feel that I need more help on this, and preferably, given my specific points below, so that I have context.

Well, after reading MVP, I decided to implement Passive Browsing. Effectively, I will have a bunch of Winform controls that will be processed by the presenter, and then tasks delegated to the model (s). My specific points are below:

  • When winform loads, it should get a treeview. Do I believe that the view should therefore call a method such as: presenter.gettree (), this, in turn, will delegate the model, which will receive data for the tree structure, create it and configure it, return it to the master, which , in turn, will move on to the view, which then simply assigns it, say, to the panel?

  • Will it be the same for any data management in Winform since I also have a datagridview?

  • My application has several classes of models with the same assembly. It also supports a plugin architecture with plugins that need to be loaded at startup. Will the view simply call the presenter method, which in turn will call the method, which loads the plugins and displays the information in the view? Which level will then control the plugin links. Will the view contain links to them or the speaker?

  • Am I right in thinking that the view should handle every thing about the view, from the node tree, to the size of a datagrid, etc.

I think these are my main problems, and if I understand how the flow should be for them, I think that everything will be fine.

+81
c # design-patterns mvp winforms
Jan 25 2018-11-11T00:
source share
3 answers

This is my humble MVP solution and your specific problems.

First , all that a user can interact with or simply show is a view. Laws, behavior and characteristics of this kind are described by the interface. This interface can be implemented using the WinForms user interface, the console user interface, a web interface, or even without an interface (usually when testing a host) - a specific implementation simply does not matter if it obeys the laws of the presentation interface.

Second , viewing is always controlled by the presenter. The laws, behavior and characteristics of such a host are also described by the interface. This interface is not interested in implementing a particular view if it obeys the laws of its view interface.

Third , since the leader controls his presentation in order to minimize dependencies, there is really no benefit in the fact that the presentation does not know anything about its leader. There, a contract is concluded between the presenter and the point of view, which is indicated by the presentation interface.

Consequences Third :

  • The host does not have any methods that the view can trigger, but there are events in the view that the host can subscribe to.
  • The host knows his opinion. I prefer to accomplish this with a constructor injection on a particular presenter.
  • The view has no idea that the host controls it; he will never be given any lead.

For your problem, the above might look like this in a slightly simplified code:

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

In addition to the above, I usually have a basic IView interface in which I put Show() and any view of the owner or title, which usually extracts my views.

To your questions:

1. When winform loads, it should get a treeview. Do I believe that the view should therefore call a method such as: presenter.gettree (), this, in turn, will delegate the model, which will receive data for the tree structure, create it and configure it, return it to the master, which , in turn, will move on to the view, which then simply assigns it, say, to the panel?

I would call IConfigurationView.SetTreeData(...) from IConfigurationPresenter.ShowView() , right before calling IConfigurationView.Show()

2. Will it be the same for any data management in Winform, since I also have a datagridview?

Yes, I would call IConfigurationView.SetTableData(...) for this. It depends on the form for formatting the data provided to it. The host simply obeys the viewing contract that he needs tabular data.

3. My application has several classes of models with the same assembly. It also supports a plugin architecture with plugins that need to be loaded at startup. Will the view simply call the presenter method, which in turn will call the method, which loads the plugins and displays the information in the view? Which level will then control the plugin links. Will the presentation contain references to them or the speaker?

If plugins are related to viewing, views should be aware of them, but not leading ones. If they are all associated with data and a model, then the view should have nothing to do with them.

4. Do I believe that a view should handle every thing about a view, from the color of the node tree, the size of the datagrid, etc.?

Yes. Think of it as a presenter providing XML that describes the data and presentation that takes the data and applies a CSS stylesheet to it. Specifically, the facilitator may call IRoadMapView.SetRoadCondition(RoadCondition.Slippery) , and the view then displays the road in red.

What about data for clicked nodes?

5. If, when I click on treenodes, I have to transfer a specific node to the leader, and then from the fact that the leader will determine what data he needs, and then asks the model for this data before presenting it back to the view?

If possible, I would transfer all the data needed to present the tree in one shot. But if some data is too large to transmit from the very beginning, or if it is dynamic in nature and needs a β€œlast shot” from the model (via the presenter), I would add something like event LoadNodeDetailsEventHandler LoadNodeDetails to the view interface, so the host can To subscribe to it, LoadNodeDetailsEventArgs.Node details from the node in LoadNodeDetailsEventArgs.Node (possibly through your identifier of some type) from the model so that the view can update the displayed node data when the delegate event handler returns. Please note that asynchronous templates may be required if data sampling may be too slow for a good user experience.

+111
Jan 27 '11 at 3:26 a.m.
source share

The host, containing all the logic in the view, should respond to a button click, as @JochemKempe says . From a practical point of view, the button event handler calls presenter.OpenFile() . The facilitator can then determine what needs to be done.

If he decides that the user should select a file, he will call back to the view (via the view interface), and let OpenFileDialog displayed in the view containing all the technical characteristics of the user interface. This is a very important difference in that the facilitator should not be allowed to perform operations related to the user interface technology used.

Then the selected file will be returned to the lead, which will continue its logic. This may include any model or service that should process the file.

The main reason for using the MVP, imo template is to separate the user interface technology from the presentation logic. In this way, the host organizes the entire logic, while the view blocks it from the user interface logic. This has a very good side effect to make the presenter a fully unified testable.

Update: since the host is the embodiment of the logic found in one particular view, the view-presenter relationship is an IMO one-to-one relationship. And for all practical purposes, one instance of the presentation (for example, a form) interacts with one instance of the presenter, and one instance of the presenter interacts with only one instance of the presentation.

However, in my MVP implementation with WinForms, the host always interacts with the view through an interface that represents the capabilities of the view's user interface. There is no restriction that the view implements this interface, so different "widgets" can implement the same view interface and reuse the presenter class.

+10
Jan 25 2018-11-11T00:
source share

The host should act at the end of the request, showing the openfiledialog window, as you suggested. Since data is not required from the model, the master can and should process the request.

Suppose you need data to create some objects in your model. You can either pass the trough stream to the access level where you have a method for creating entities from the stream, but I suggest you handle the file parsing in the presenter and use the constructor or the Create method for each object in your model.

+2
Jan 25 2018-11-11T00:
source share



All Articles