3

I'm trying to implement the Model-View-Presenter design pattern in my application. The general concept of the MVP pattern is known for me, but I'm more struggling with getting it done using nested usercontrols.

I've got a few possible scenarios I might be able to implement, but before doing so I'd like to hear your opinion.

I think it does not matter to post any of my code, since its more a "concept" I'm trying to understand.

So the scenario is:

1 page used to connect 2 user controls. One of these usercontrols contains a child usercontrol. How do I work around with MVP pattern in this case?

1 Page
  1 UC
  1 UC
     1 SubUC

Edit:

So basicly what I want to know is how we can interact between two views (parent and child) using MVP in both usercontrols.

I'll show you an example in ASP.net WITHOUT MVP: http://pastie.org/5452134

Now with MVP, do we still register to this kind of event using the CodeBehind? Knowing that this parent and child usercontrol would both be using the MVP pattern. Or does the presenter get's included in this interaction?

Eventually I can change the code to: http://pastie.org/5452180

But I'm wondering whether this is OK, considering the MVP pattern...

Or do we more need an approach like this: http://pastie.org/5452174

All the above examples are written in the CodeBehind of the parent view. Is one of this correct? If not, how can we achieve this using a better approach

Edit 2: I've added a solution with my example approach at: https://github.com/frederikprijck/ASP.NET-MVP I think this should be pretty much what I wanted...

Frederik Prijck
  • 1,424
  • 10
  • 16
  • I am not entirely sure what is your problem exactly? What exactly is the relation between MVP pattern and UserControls here? See a short example of MVP pattern here: http://www.codeproject.com/Articles/134692/Model-View-Presenter-Pattern-Implementation-in-ASP – VinayC Nov 29 '12 at 08:36
  • The relation? MVP Patterns can be used inside usercontrols just like inside pages. This link you're providing does not even talk about user controls? So what I want to achieve is a MVP pattern implementation inside my UserControls. FYI: I know how MVP works, I'm not asking for how to set it up... I'm asking for best practises for working with nested UserControls. – Frederik Prijck Nov 29 '12 at 08:46

1 Answers1

5

I don't see a problem - user control is nothing but a view. And a presenter can interact with multiple views at a time. So in this case, your presenter can have reference of say 4 views (one for page, two for user controls and last one for sub-user control).

Alternatively, you want to have single view per presenter and in such case, you can see user control as child view of the parent view(page) and so parent view need to bubble up and down view interactions meant for presenter. However, I would prefer the earlier approach where presenter handling interaction multiple views.

See this related question on SO on how wiring is done: https://softwareengineering.stackexchange.com/questions/60774/model-view-presenter-implementation-thoughts

Finally, you may want to look at MVVM pattern which I believe works great for compositional UI. Instead of presenter, you will have view model that will control the interaction between view and model - however, unlike presenter, view model does not know about view - rather view observes (and updates) view model to render itself. See this article here (View Model is referred as Presentation Model): http://www.codeproject.com/Articles/23340/Presentation-Model-in-Action

EDIT:

To be honest, I don't prefer any of your approaches. I like MVP implementation where presenter holds reference to view via interface (no tight coupling) and view does the wiring i.e. creates presenter instance and inject the view references. The presenter listens to view events and call methods on view. View never calls directly on presenter's methods. (Other variations of MVP are possible - see the SO answer that I had sought). With this, I will explain two approaches that I had explained earlier.

Approach 1:

Each user control is an independent view. There will be common presenter that will handle multiple views. For example,

public class Presenter1
{
    IView1 _view1;
    IView2 _view2;

    public Presenter1(IView1 view1, IView2 view2)
    {
        _view1 = view1;
        _view2 = view2;

        _view1.OnSave += OnSave;
        _view1.OnSomeEvent += OnSomeEvent;
        _view2.OnFoo += OnFoo;
    }

    public void OnSave()
    {
        var data1 = _view1.GetData();
        var data2 = _view2.GetData();
        // update model
        ...
    }

    public void OnSomeEvent()
    {
       // inform view2 about it
       _view2.DoOnSomeEvent();
    }

    ...
}

public partial class MyPage : Page, IView1
{
   public void Page_Load(...)
   {
     //do wire up
     _presenter = new Presenter(this, usercontrol1);
   }
   ...
}

Basic idea is that view does not do cross talk. If user control needs to inform page some thing, it would raise an event that is caught by presenter and it informs page about it. Views are passive and handles UI.

Approach 2:

Usercontrol and Page interacts. In such case, Page will act as a ultimate view and Presenter will hold reference to it. Control's events will be handled by page and page will bubble up the event if necessary. For example,

IView1 : IView2 { }

public class Presenter1
{
   IView1 _view1;

   public Presenter1(IView1 view1)
   {
       _view1 = view1;

       _view1.OnSave += OnSave;
       _view1.OnSomeEvent += OnSomeEvent;
       _view1.OnFoo += OnFoo;
   }
   ...
}

public partial class MyPage : Page, IView1
{
       public void Page_Load(...)
       {
         //do wire up
         _presenter = new Presenter(this);

         // handle user control events
         UserControl1.Foo += UserControl1_OnFoo();
         UserControl1.XyzEvent += UserControl1_XyzEvent();

       }
       ...

       private void UserControl1_OnFoo(...)
       {
          // bubble up to presenter
          OnFoo(..)
       }

       private void UserControl1_XyzEvent(...)
       {
          // private interaction (purely about some UI manipulation), 
          // will not be bubble up to presenter
          ...
       }
}
Community
  • 1
  • 1
VinayC
  • 47,395
  • 5
  • 59
  • 72
  • I know how MVVM works but I'm using MVP here. As said I also know how MVP works, I'm just abit confused about how to connect different usercontrols with each other. Thank you for your answer, but it does not realy answer what I am looking for. I'm not looking for how to set up MVP, but how to work with multiple user controls using MVP and their interaction. (events of child UserControls etc) If I would use 1 view/1presenter per usercontrol, how do I work with the child usercontrol? Do I initialize the child control his presenter inside the parent's presenter? – Frederik Prijck Nov 29 '12 at 09:43
  • And then eventually, how do I communicate from the child back to the parent... Without MVP I'd do this using events in the CodeBehind file. But is this still the same when working with MVP? I'll change my post to be more clear – Frederik Prijck Nov 29 '12 at 09:52
  • @FrederikPrijck, see my edit to understand what I am suggesting. – VinayC Nov 30 '12 at 06:15
  • U said: "To be honest, I don't prefer any of your approaches. I like MVP implementation where presenter holds reference to view via interface (no tight coupling)", just to clearify... I am using an interface, I just did not pasted that since that's not part of the problem – Frederik Prijck Nov 30 '12 at 07:55
  • I don't like both of you approaches since I want both of my views to run seperatly... If both views should not be required to run seperatly I would go for your first option. But since I want View 1 and its presenter to work independently from View 2 and its presenter... So what I am thinking is I will need a modified version of your first example... – Frederik Prijck Nov 30 '12 at 07:56
  • Your examples are interesting btw, Don't get me wrong! It helped me a bit, but I think I am still not there. I'll make a setup about what I think I need and I'll paste it here in a few hours ok? Thanks for helping :) – Frederik Prijck Nov 30 '12 at 08:00
  • @FrederikPrijck, I guess what you want is to have independent presenters for each user control. In such case, wiring of these presenters and controlling interactions between them has to be taken outside - a page class (or a even independent controller class) would be a better choice. Also see http://stackoverflow.com/questions/429500/mvp-and-usercontrols-and-invocation – VinayC Nov 30 '12 at 09:14
  • VinayC, if you have the time could you take a look at : https://github.com/frederikprijck/ASP.NET-MVP It should be easier to understand what I am trying to achieve... I have added one TODO: comment line where I guess I'm not doing it the way it should. – Frederik Prijck Nov 30 '12 at 09:25