views:

739

answers:

2

Edit : Accepted Chris Holmes response, but always ready to refactor if someone come up with a better way! Thanks!

Doing some winforms with MVP what is the best way to pass an entity to another view.

Let say I have a CustomerSearchView/Presenter, on doubleClick I want to show the CustomerEditView/Presenter. I don't want my view to know about the model, so I can't create a ctor that take an ICustomer in parameters.

my reflex would be,

CustomerSearchView create a new CustomerEditView, which create it's own presenter. Then my customerSearchView would do something like :

var customerEditView = new CustomerEditView();

customerEditView.Presenter.Customer = this.Presenter.SelectedCustomer;

Other possible approach would be a CustomerDTO class, and make a CustomerEditView that accept one of those CustomerDTO, but I think it's a lot of work something simple.

Sorry for basic question but all example I can find never reach that point, and it's a brownfield project, and the approach used soo far is giving me headache...

Thanks!

+1  A: 

How about:

//In CustomerSearchPresenter
var presenter = new CustomerEditPresenter();
var customerEditView = new CustomerEditView(presenter);
presenter.SetCustomer(customer);

//In CustomerEditPresenter
public void SetCustomer(customer)
{
    View.Name = customer.Name;
    View.Id = customer.Id;
    ...
}

In think your customer search view should just delegate to its presenter you need to have an action execute.

Simon Laroche
You misspelled "presenter" as "presneter", above.
Mark Rogers
well that almost like I said except that you use a method instead of a property to set the customer. Thanks.
pmlarocque
The difference is in who has what responsibilities. In your example setting the customer in view code implies that the view knows how to get a customer. That should be left to the presenter.
Simon Laroche
+2  A: 

I don't know exactly how you are showing your views, so it's a bit difficult to give you specific advice here. This is how I've done this sort of thing before:

What we did was have the CustomerSearchViewPresenter fire an event like OpenCustomer(customerId). (That is assuming that your search view only has a few pieces of Customer data and the customerId would be one of them. If your search view has entire Customer objects listed then you could call OpenCustomer(customer). But I wouldn't build a search view and allow it to populate with entire objects... We keep our search views lightweight in terms of data.)

Somewhere else in the application is an event handler that listens for the OpenCustomer() event and performs the task of creating a new CustomerEditView w/ Presenter (and I'm going to defer to my IoC container do this stuff for me, so I don't have to use the "new" keyword anywhere). Once the view is created we can pass along the id (or customer object) to the new CustomerEditView and then show it.

This class that is responsible for listing the OpenCustomer() event and performs the creation of the CustomerEditView is typically some sort of Controller class in our app.

To further simplify this situation, I've done this another way: I create both the CustomerSearchView (& presenter) and CustomerEditView (& presenter) when the application or module starts up. When the CustomerSearchView needs to open a Customer for editing, the CustomerEditView becomes the responder to the OpenCustomer event and loads the data into itself, and knows how to show itself in whatever container it is supposed to do.

So there's multiple ways to do this.

Chris Holmes
I think events are a good approach to this problem and as you said in conjunction with a IoC it make very clean code.
pmlarocque