Winforms – MVP and UserControls and invocation

design-patternsmvpuser interfacewinforms

I'm having some fun trying to get my head around some MVP stuf, as it pertains to User Controls. I'm using .NET WinForms (or something close to it) and Supervising Controller pattern (well, I think I am :).

The User Control is itself part of an MVP application (its the View and has an associated Presenter etc). The Presenter is always started first, and it starts the Model(s) and then View(s). The View builds its UI, part of which will be to NEW the UC, which is the View.

Now the (form) Presenter needs to know about the UC Presenter, but I'm thinking that it doesn't know anything about how the View is composed. The form Presenter doesn't, for instance, know that the UC is part of the form's Controls collection, nor should it.

Furthermore, the design experience should not be changed; IOW the dev of the View (form) should just be able to select a User Control from the toolbox and drop it on a form.

So, on to my questions. Firstly, are my assumptions above correct? Somewhat misguided? Messed up? WTF are you thinking?

Secondly, is it right (enough?) to have the form View invoke the UC View, and the form Presenter invoke the UC Presenter and have some mechanism to tell the UC View what its Presenter is? This breaks my "Presenter first" rule, but I'm not sure how else to do it.

Any other thoughts, suggestions, comments gladly accepted.

— nwahmaet

Best Answer

A presenter should be thought of as "autonomous state" in the presentation tier. This means that it is responsible for ensuring that the view's presentation of the model's state is in sync. The reason I bring this up is because the "pattern" of MVP often gets lost in the dogmatic view of how things should be separated. It seems that this is one reason Martin Fowler decided to try to clarify the terminology around the MVP pattern.

My favored flavor of MVP is the passive view, so my answer is based off of that.

I implement composite user controls and forms very often using the passive view pattern. There are essentially 3 different configurations:

  1. One presenter for all user controls in the hierarchy. Flatten the view using an interface.
  2. One presenter for each user control in the composite tree. Each parent presenter is responsible for instantiating and initializing its child presenters. The user controls are created at design time, and are able to function without a presenter (with no presentation behavior)
  3. One presenter for each user control in the composite tree. All of the presenters are loosely coupled through a higher level controller class. The controller class is responsible for construcing the presenter, wiring them up, and coordinating their events.

Although it is a solution of last resort for me (because of its complexity), I think that the last option is the solution that you are looking for.