/ / WPF DataTemplate / DataTemplateSelector - Il miglior approccio per un ViewModel utilizzato da 2 viste diverse? - wpf, mvvm, prism, datatemplate, datatemplateselector

WPF DataTemplate / DataTemplateSelector - L'approccio migliore per un ViewModel utilizzato da 2 diverse viste? - wpf, mvvm, prism, datatemplate, datatemplateselector

Fondamentalmente, ho il seguente scenario:

ViewModel: FooViewModel : BaseViewModel, BarViewModel : BaseViewModel
Visualizzazioni: MainView, FooView, BarView

In questo momento "iniettare" la vista e impostare il DataContext utilizzando DataTemplate e DataTemplateSelector. Ovviamente mio ItemsControl ItemSource è legato a un ObservableCollection<BaseViewModel> in cui contiene (per ora) un'istanza di a FooViewModel e a BarViewModel

Il problema è che voglio introdurre a AlternateFooView che voglio utilizzare lo stesso FooViewModel. Immagino che ne creerò un altro DataTemplate e ho il mio DataTemplateSelector restituirlo, ma ci deve essere una logica speciale perdeterminare quale DataTemplate restituire (non posso semplicemente passare da quale ViewModel è presente) e ciò significa che dovrò avere un tipo di proprietà o campo in BaseViewModel. Non so se sia davvero una buona idea perché sembra introdurre un campo / proprietà nel ViewModel che viene utilizzato solo per selezionare una vista. Non danneggerà i test delle mie unità, ma sembra uno spreco includere un campo solo per aiutare a decidere quale UI View scegliere. Non credo che rompa MVVM, ma sono curioso di sapere se qualcuno là fuori ne ha altri idee migliori? Le idee alternative che ho avuto non mi piacciono ancora di più ...

Idea n. 2:
- Trasforma FooViewModel in una classe base che 2diversi estensioni di FooViewModel (ovvero BaseFooViewModel, FooViewModel, DifferentFooViewModel). Questo sembra stupido perché non c'è davvero alcuna differenza tra FooViewModel e DifferentFooViewModel a parte il loro tipo di classe.

Idea n. 3:
- Basta copiare FooViewModel e renderlo FooViewModel2 (sarà esattamente identico a FooViewModel). Questo sembra anche peggio dell'idea n. 2.


Codice di esempio (modificato ovviamente):

public abstract class BaseViewModel : NotificationObject
{
//Common Stuff
}

public abstract MainViewModel : NotificationObject
{
public MainViewModel()
{
MyItems = new ObservableCollection<BaseViewModel>()
{
new FooViewModel();
new BarViewModel();
new FooViewModel(); //New Item -- I want it to use the DifferentFooView
}
//Load items from a DAL later
}

public ObservableCollection<BaseViewModel> MyItems { get; set; }

//Other Stuff
}

<l:MyItemsControl ItemSource={Binding MyItems} ContentTemplateSelector={StaticResource MyTemplateSelector} />


Grazie!

risposte:

4 per risposta № 1

Sono d'accordo con Krishnaaditya che la domandasi riduce davvero a ciò che determina quale vista utilizzare in base allo stato di ViewModel. Questo tipo di logica viene spesso inserito in un selettore di modelli, che funziona alla grande. Se non vuoi mettere quella logica nel selettore di template, considera di esternalizzarla usando my Selezione del modello indirizzato approccio. Ciò semplifica la delega della logica di selezione del modello utilizzando un evento indirizzato.

L'idea che hai proposto nel tuo commento sull'utilizzoun DataTrigger potrebbe anche funzionare, ma ciò reintroduce la necessità di una proprietà sull'oggetto VM che indica quale Vista caricare (che hai detto che non vuoi). A mio avviso, non è necessariamente una cosa negativa.