4

I've been working with MVVM for a while, but I've recently started using MVPVM and I want to know how to create hierarchial View/ViewModel/Presenter app using this pattern.

In MVVM I would typically build my application using a hierarchy of Views and corresponding ViewModels e.g. I might define 3 views as follows:

View A

The View Models for these views would be as follows:

public class AViewModel
{
    public string Text
    {
        get { return "This is A!"; }
    }

    public object Child1 { get; set; }    
    public object Child2 { get; set; }
}

public class BViewModel
{
    public string Text
    {
        get { return "This is B!"; }
    }
}

public class CViewModel
{
    public string Text
    {
        get { return "This is C!"; }
    }
}

In would then have some data templates to say that BViewModel and CViewModel should be presented using View B and View C:

<DataTemplate DataType="{StaticResource local:BViewModel}">
    <local:BView/>
</DataTemplate>
<DataTemplate DataType="{StaticResource local:CViewModel}">
    <local:CView/>
</DataTemplate>

The final step would be to put some code in AViewModel that would assign values to Child1 and Child2:

public AViewModel()
{
    this.Child1 = new AViewModel();
    this.Child2 = new BViewModel();
}

The result of all this would be a screen that looks something like:

enter image description here

Doing this in MVPVM would be fairly simple - simply moving the code in AViewModel's constructor to APresenter:

public class APresenter 
{
    ....
    public void WireUp()
    {
        ViewModel.Child1 = new BViewModel();
        ViewModel.Child2 = new CViewModel();
     } 
}

But If I want to have business logic for BViewModel and CViewModel I would need to have a BPresenter and a CPresenter - the problem is, Im not sure where the best place to put these are.

I could store references to the presenter for AViewModel.Child1 and AViewModel.Child2 in APresenter i.e.:

public class APresenter : IPresenter
{
    private IPresenter child1Presenter;
    private IPresenter child2Presenter;

    public void WireUp()
    {
        child1Presenter = new BPresenter();
        child1Presenter.WireUp();
        child2Presenter = new CPresenter();
        child2Presenter.WireUp();

        ViewModel.Child1 = child1Presenter.ViewModel;
        ViewModel.Child2 = child2Presenter.ViewModel;
    }
}

But this solution seems inelegant compared to the MVVM approach. I have to keep track of both the presenter and the view model and ensure they stay in sync. If, for example, I wanted a button on View A, which, when clicked swapped the View's in Child1 and Child2, I might have a command that did the following:

var temp = ViewModel.Child1;
ViewModel.Child1 = ViewModel.Child2;
ViewModel.Child2 = temp;

This would work as far as swapping the view's on screen (assuming the correct Property Change notification code is in place), but now my APresenter.child1Presenter is pointing to the presenter for AViewModel.Child2, and APresenter.child2Presenter is pointing to the presenter for AViewModel.Child1. If something accesses APresenter.child1Presenter, any changes will actually happen to AViewModel.Child2. I can imagine this leading to all sorts of debugging fun.

I know that I may be misunderstanding the pattern, and if this is the case a clarification of what Im doing wrong would be appreciated.

EDIT - this question is about WPF and the MVPVM design pattern, not ASP.NET and MVP.

2

2 Answers 2

2
+50

So I think you have some minor violation of MVVM | MVPVM patterns due to linkage you're creating between the views. Neither pattern is all that verbose with respect to child windows though, so it's a bit of a murky area.

I think it's worth pointing out that the big advantage of MVPVM vs. MVVM is because of separating out business logic. The VM becomes a data container and the P handles logic plus DAL access. Bill Kratochvil's article on MVPVM was a very good read.

Bill makes a comment regarding child windows and re-use that I think is apt:
In cases where a Presenter can be reused across enterprise applications, it’s likely a module would be better suited for the task—that is, you could create a login module (project) that could be reused by all of your enterprise applications.

Which kind of reinforces that you're in murky territory with two child components.

Regardless of MVVM or MVPVM, I think you would need either

  • B-VM and C-VM when using MVVM
  • B-P and C-P and B-VM and C-VM when using MVPVM

because they are functionally separate from A. If they're not functionally separate, then why do they need their own Views?

I think the challenges you bring up with swapping ViewB and ViewC is because there is some blurring between object ownership and responsibilities. Which is really just another way of asking if B and C are functionally separate from A or not. If they are, then make them that way and if not, then don't set them up as independent.

For lightweight stuff without a lot of business logic that could be re-used, I think that MVPVM is more effort than it's worth with MVVM. That's clearly a generality, and the business logic of your application may lend itself to being expressed more elegantly with MVPVM. Based upon your question though, it sounds like MVVM may be sufficient for what you need.

4
  • Thanks Glen, Im awarding you the Bounty because it seems you are correct in that there unfortunately it seems there is really no way of doing what I want to do. Dec 5, 2012 at 9:41
  • My example probably wasnt all that clear I think - swapping B and C wasnt the best illustration of the type of thing I want to do. Another similar problem would be if I have a main view with a list of items that I can select, to the right of that list I have a details panel, but the actual view I display in there changes depending on the item I've selected from the list. Dec 5, 2012 at 9:45
  • @BrianFlynn - I've been mulling your newer example in my head and trying to think through handling that. So it sounds like there are a number of "details panels" variants that need to be swapped out based upon the selection in the main panel. I don't think that MVVM or MVPVM address that functionality, although MVPVM is probably better structured for it. Some of the logic on "which view" to select can be pushed to MVPVM.
    – user53019
    Dec 5, 2012 at 12:23
  • Its fairly easy in MVVM - put an property on the main ViewModel called 'DetailViewModel', with return type object - this property is the ViewModel of the View to be displayed. In the main View you put a ContentControl where the details panel goes, and bind its 'Content' to the 'DetailViewModel' property. The last step is to create a DataTemplate in your main View resources that maps a particular ViewModel to a View. e.g. <DataTemplate DataType="{x:Type ViewModels:ViewModelB"><Views:ViewB/></DataTemplate>. This tells WPF that to display an object of type 'ViewModelB' use the view 'ViewB'. Dec 7, 2012 at 4:58
0

If you are swapping the ViewModel, shouldn't you swap the presenter too?

Anyway, I've been researching the MVP pattern. I'm far from understanding. But I can you give you some links that are helping me:

http://lostechies.com/derekgreer/2008/11/23/model-view-presenter-styles/

http://webclientguidance.codeplex.com/wikipage?title=HowToImplementModelViewPresenterPattern&referringTitle=HowToUnitTestPresenter

In the end, there's no right way of implementing it. I've read somewhere that if you put 10 programmers in a room discussing MVP, you'll get 11 different implementations. You should do whatever works best for you.

If I'm not the mistaken this patterns are there to help separate the concerns, and also help you test your code. Try variations and see what works better for you.

2
  • "If you are swapping the ViewModel, shouldnt you swap the presenter too?" - this was partly the point I was trying to make - you have two things to set every time you want to set a child view - which is imo inelegant and prone to errors (if you swap the views, but not the presenters, it will superficially work, and pass some basic testing, but cause all sorts of weird problems with more complex use). Dec 5, 2012 at 9:50
  • RE: the MVP links you posted, thanks, but I'm specifically interested in MVPVM (I'd have tagged it as such, but the tag doesnt exist, and MVP and MVVM are the two closest patterns). Dec 5, 2012 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.