3

In a conventional MDI WinForms application, one would go like this:

public partial MainMdiForm : Form {
    public MainMdiForm() { InitializeComponent(); }

    private void manageCustomersToolStripMenuItem_Click(object sender, EventArgs e) {
        var cmf = new CustomerManagementForm();
        cmf.MdiParent = this;
        cmf.Show();
    }
}

So that the CustomerManagementForm never gets out of bounds.

Using Model-View-Presenter along with Dependency Injection, the code adds an abstraction layer which actually doesn't allow me to set the MdiParent of my view/form.

MainMdiForm

public partial MainMdiForm : Form, IMainView {
    public MainMdiForm() { InitializeComponent(); }

    public IMainViewUiHandler Handler { get; set; }

    private void manageCustomersToolStripMenuItem_Click(object sender, EventArgs e) {
        Handler.ManageCustomers();
    }
}

IMainView

public interface IMainView : IView, IHasUiHandler<IMainViewUiHandler> { }

IHasUiHandler

public interface IHasUiHandler<H> where H : IUiHandler {
    H Handler { get; set; }
}

IUiHandler

public interface IUiHandler { }

IMainViewUiHandler

public interface IMainViewUiHandler : IUiHandler { 
    void ManageCustomers();
}

MainPresenter

public class MainPresenter : Presenter<IMainView>, IMainViewUiHandler {
    public MainPresenter(IMainView view
        , ICustomerManagementPresenterFactory customerManagementPresenterFactory) 
        : base(view) {
        view.Handler = this;
        this.customerManagementPresenterFactory = customerManagementPresenterFactory;
    }

    public void ManageCustomers() {
        var p = customerManagementPresenterFactory.Create();
        p.ShowView();
    }

    private readonly ICustomerManagementPresenterFactory customerManagementPresenterFactory;
}

As you can see, there's nowhere to set the Form.MdiParent property for the view that the presenter handles. And exposing such property might break the abstraction and tight couple it to WinForms, since no other platform uses such a hierarchy with the different user-interfaces. Although this application is destined to be a simple example of using MVP along with DI, I wish to make it as clean as possible.

I thought of creating a single interface which would use the Parent terminology, and compose my view with it only from within the Windows Forms application, so that other platforms would not inherit from this useless property.

Any idea on how I should go along with this?

  • Are you sure that other windowing platforms in majority don't have the concept of a parent window/widget. In any case, you could pass a Form reference in the calls to ManageCustomers and Create and let the factory class determine if it needs a parent link or not and in which property to set it. – Bart van Ingen Schenau Sep 24 '14 at 7:11
  • @BartvanIngenSchenau, In short, I can't say that I am sure. To the best of my knowledge, WPF, ASP.NET, and Silverlight don't have this concept. I might be mistaking, I perhaps only never needed such concept on other platforms than WinForms. – Will Marcouiller Sep 24 '14 at 13:15
  • How about you introduce a UI hooking context? The context could be abstract but have one implementer that is aware of the MDI window mechanics and take care of attaching child windows correctly upon call to ShowView. The hooker could be a parameter to the latter, distributed by the MDI parent view (as an hooker interface, for example). – Crono Sep 24 '14 at 14:05
  • So I could use an interface with a single property for which my form holds an implementation, and pass it upon a call to ShowView like so: Presenter.ShowView(myParentChildInterface). Is this what you're proposing, do I get it correctly? – Will Marcouiller Sep 24 '14 at 14:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.