Search code examples
c#winformsmodel-view-controlleruser-interfacemvp

How is coordination of child views best handled in MVP?


I am attempting to use MVP in WinForms and am confused on how to best handle coordination among child views.

For example, I have a parent view that has two child views. Events on one child view need to cause an action to be taken by the second child view.

Should the parent view control this directly? It seems like I am bypassing the MVP pattern by doing this.

Or should the child views take each other as constructor parameters? In that case, when an event was fired by the first child view, the 2nd child view would receive the event and then notify its presenter that something has occurred? The presenter then needs to get the data from the first child view (which it doesn't even know about) in order to tell the 2nd child view what to do. It seems convoluted so I feel like I am missing something.

Here is some pseudo-code for the situation:

public class ParentView : UserControl, IParentView
{
    private ChildViewOne childViewOne;
    private ChildViewTwo childViewTwo;
    private ParentViewPresenter presenter;

    private RegisterEvents()
    {
        childViewOne.EventOccured += new EventHandler(HandleEvent);
    }

    private void HandleEvent()
    {
        childViewTwo.DoSomething();
    }
}

Solution

  • You could look at the Event Aggregator pattern. It will allow you to keep everything loosely coupled. Prism comes with one and it's easy enough to use without having to buy into the whole Prism framework/library.

    Your code could then look like this:

    public class ChildViewOne {
        private IEventAggregator evtAggregator;
    
        public ChildViewOne(IEventAggregator evtAggregator) {
            this.evtAggregator = evtAggregator;
        }
    
        private void OnEventOccured(){
            evtAggregator.GetEvent<EventOccured>().Publish();
        }
    }
    
    publish class ChildViewTwo {
        private IEventAggregator evtAggregator;
    
        public ChildViewTwo(IEventAggregator evtAggregator) {
         evtAggregator.GetEvent<EventOccured>().Subscribe(OnEventOccured);
        }
    
        private void OnEventOccured() {
            // Do something here...
        }
    }
    

    EDIT: Brian Noyes has ported the prism event aggregator to winforms. Check it out here, on his blog