Lavoro con MVVM da un po ', ma di recente ho iniziato a utilizzare MVPVM e voglio sapere come creare l'applicazione View / ViewModel / Presenter gerarchica usando questo modello.
In MVVM tipicamente creerei la mia applicazione utilizzando una gerarchia di viste e corrispondenti ViewModels, ad es. Potrei definire 3 visualizzazioni come segue:
Imodellidivistaperquestevistesarebberoiseguenti:
publicclassAViewModel{publicstringText{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 avrebbe quindi alcuni modelli di dati per dire che BViewModel e CViewModel dovrebbero essere presentati usando View B e View C:
<DataTemplate DataType="{StaticResource local:BViewModel}">
<local:BView/>
</DataTemplate>
<DataTemplate DataType="{StaticResource local:CViewModel}">
<local:CView/>
</DataTemplate>
Il passaggio finale sarebbe inserire un codice in AViewModel che assegnerebbe valori a Child1 e Child2:
public AViewModel()
{
this.Child1 = new AViewModel();
this.Child2 = new BViewModel();
}
Il risultato di tutto questo sarebbe uno schermo simile a questo:
Fare questo in MVPVM sarebbe abbastanza semplice - semplicemente spostando il codice nel costruttore di AViewModel in APresenter:
public class APresenter
{
....
public void WireUp()
{
ViewModel.Child1 = new BViewModel();
ViewModel.Child2 = new CViewModel();
}
}
Ma se voglio avere una logica di business per BViewModel e CViewModel dovrei avere un BPresenter e un CPresenter - il problema è, non sono sicuro di dove sia il posto migliore per metterli.
Potrei memorizzare riferimenti al presentatore per AViewModel.Child1 e 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;
}
}
Ma questa soluzione sembra inelegante rispetto all'approccio MVVM. Devo tenere traccia sia del relatore che del modello di visualizzazione e assicurare che rimangano sincronizzati. Se, ad esempio, volevo un pulsante nella vista A, che, quando si faceva clic su Vista in Child1 e Child2, potevo avere un comando che eseguiva le seguenti operazioni:
var temp = ViewModel.Child1;
ViewModel.Child1 = ViewModel.Child2;
ViewModel.Child2 = temp;
Questo funzionerebbe fino a scambiare la vista sullo schermo (supponendo che sia presente il corretto codice di notifica di modifica proprietà), ma ora il mio APresenter.child1Presenter punta al presentatore per AViewModel.Child2 e APresenter.child2Presenter punta a il presentatore per AViewModel.Child1. Se qualcosa accede a APresenter.child1Presenter, qualsiasi modifica verrà effettivamente eseguita in AViewModel.Child2. Posso immaginare questo che porta a tutti i tipi di divertimento di debug.
So che potrei fraintendere il modello, e se questo è il caso, sarà apprezzato un chiarimento su ciò che sto facendo.
EDIT : questa domanda riguarda WPF e il modello di progettazione MVPVM, non ASP.NET e MVP.