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:
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:
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.