9

I'm dealing with a big problem for developing my app. It's a Winforms base application on C# implementing the Model-View-Presenter pattern, but I am new to this method. I've searched everywhere and haven't found an answer to my issue.

I need to know how I can use this pattern to allow communication between winforms, and how the presenter must show them without coupling the presenter to the form. I've seen a way using Factory pattern, but don't understand how to implement it.

Any help or point in the right direction would be appreciated.

Deanna
  • 23,876
  • 7
  • 71
  • 156
  • Can you provide an example of how you are currently attempting to implement this? Can you provide a link to technique using the Factory pattern that you don't understand? – jeuton Feb 13 '13 at 18:03

4 Answers4

3

Assertion

The Presenter is responsible for coordination between the View and Model (if following the Passive View implementation).

This could look like:

A View instantiating the Presenter and injecting itself into the Presenter:

IPresenter presenter;
public View() { presenter = new Presenter(this) }

A Presenter instantiating one or more views and injecting itself into the view(s):

IView1 view1;
public Presenter() { view1 = new View1(this) } 

IView1 view1;
IView2 view2;
public Presenter() { view1 = new View1(this); view2 = new View2(this); }

Example

In your case, a Presenter coordinating multiple views might look something like this (pseudo):

public class Presenter : IPresenter
{
  IView1 view1;
  IView2 view2;
  public Presenter() 
  {
    view1 = new View1(this);
    view2 = new View2(this);
  }

  private WireViewEvents()
  {
    view1.OnButtonClick += HandleButtonClickFromView1;
  }

  public void HandleButtonClickFromView1()
  {
    view2.SetSomeData();
    view2.Show();
}

In this example, an event raised by View1 is handled by the Presenter, data is set in View2, and View2 is shown.

Keep in mind that no matter what your implementation is, the goals of MVP are:

  • Separation of concerns (UI seperate from domain logic).
  • Increasing testability.

Keep that this is just a basic example of how a Presenter might coordinate multiple views. If you want to abstract your View creation from the presenter you might move the creation into another container that the Presenter calls in to to create Views and subscribe to their events.

jeuton
  • 543
  • 3
  • 7
  • do we really need IPresenter? I dont think so its a good idea for a presenter. Can you explain why we can need IPresenter in MVP? – Sandy Feb 14 '13 at 11:54
  • In my example the IPresenter interface doesn't directly pertain. That said, if the `View` is the one injecting itself into the Presenter (first code snippet) its makes a lot of sense. By making the Presenter implement an interface you allow the View to wire itself up *any* class that implements that interface. – jeuton Feb 14 '13 at 14:15
  • For example, your view might call into a Factory method to get the right Presenter (it doesn't directly instantiate the presenter in the constructor as in my example above). You might have an `AdminUserPresenter : IPresenter`, a `RegUserPresenter : IPresenter`, and a `GuestUserPresenter : IPresenter`. The `View` would have no idea what presenter it is talking to (because it's getting the presenter from a Factory). The `View` only knows that it's talking to an IPresenter. – jeuton Feb 14 '13 at 14:16
  • I guess, if your `View` is serving more than one purpose then it is IPresenter is useful. Is my understanding is correct? – Sandy Feb 14 '13 at 14:45
  • It's also useful if the `View` had only 1 `Presenter` in that you are abstracting the concrete dependency on the `Presenter` away from the `View` (The `View` is loosely coupled to an interface rather than tightly coupled to a concrete type). You are correct though in that it is not "necessary". – jeuton Feb 14 '13 at 15:31
  • More reading on "Programming to an interface, not an implementation" can be found [here](http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface), and [here](http://www.fatagnus.com/program-to-an-interface-not-an-implementation/) – jeuton Feb 14 '13 at 15:35
  • Sure. I will edit my response to include some of the things we discussed in the comments – jeuton Feb 14 '13 at 20:10
3

In MVP ,winforms should not communicate with each other. Form A knows its Presenter A, Form B knows its presenter B

Usually , you will modify model with form A through Prensenter A. Presenter B will listen to model changes,and will refresh Form B accordingly

If you need more coordination, you may consider using an Application Controller

See http://dotnetslackers.com/articles/designpatterns/The-Presenter-in-MVP-Implementations.aspx

flamandier
  • 502
  • 4
  • 6
1

I am just showing a dummy code in which 2 views are trying to communicate to each other through Presenter using interfaces. It is a simple example and let mw know if something is breaking. I have not tested this code to be honest.

namespace WindowsFormsApplication1
{
    internal class View1 : IView1
    {
        public View1()
        {
            new Presenter(this);
        }


        public string Username { get; set; }
        public event EventHandler ShowDetails;
    }
}

namespace WindowsFormsApplication1
{
    internal class View2 : IView2
    {
        public View2()
        {
            new Presenter(this);
        }

        public string Position { get; set; }
    }
}

namespace WindowsFormsApplication1
{
    public class Presenter
    {
        private readonly IView1 _view1;
        private readonly IView2 _view2;

        public Presenter(IView1 view1)
        {
            _view1 = view1;
            _view1.ShowDetails += ShowDetails;
        }

        private void ShowDetails(object sender, EventArgs e)
        {
            _view2.Position = _view1.Username == "My Name" ? "Arhchitect" : "Project Manager";
        }

        public Presenter(IView2 view2)
        {
            _view2 = view2;
        }

    }

}

public interface IView1
{
    string Username { get; set; }

    event EventHandler ShowDetails;
}

public interface IView2
{
    string Position { get; set; }
}

But after this example some notes. To start with your application try to decide first weather you want to go with 1 View interface or 2. There may be chances and even ease if you can use a single interface.

Sandy
  • 11,332
  • 27
  • 76
  • 122
0

I think the points made earlier about the model raising events to make a presenter aware of changes is correct. I do have a couple comments I hope will be useful.

First, the View implementation might not be a single form. Sometimes, it makes sense for part of the model to be maintained by a separate (probably modal) form that really acts like a complex control in the View. In that case, the interaction between the forms would be direct. The Presenter should not care how the View implementation is done.

Second, when it looks like forms need to interact that are not clearly part of the same view (a lookup form, for example) I would recommand using the Application Controller pattern. In this case, when Form A needs to perform a function (like, "Find Product" or "Edit Details") it will call a method on it's own Presenter to do that. The Presenter then calls a separate method on the Application Controller (which all Presenters reference, it's a singleton) and the Application Controller opens the requried form which has its own Presenter. In WinForms, this could all be done with a modal form, in which case the results are sent back through the call chain. Alternatively, some event raising between the Application Controller and Presenters would be needed - i.e. the Presenter raises events on the Application Controller about what it has done and other Presenters substribing to that event are thus notified.

More on the Application Controller pattern in MVP can be found on my blog post Using the MVP Pattern