/ / WPF DataTemplate / DataTemplateSelector - Najlepsze podejście do modelu ViewModel używanego przez 2 różne widoki? - wpf, mvvm, prism, datatemplate, datatemplateselector

WPF DataTemplate / DataTemplateSelector - Najlepsze podejście do ViewModel używane przez 2 różne widoki? - wpf, mvvm, prism, datatemplate, datatemplateselector

Zasadniczo mam następujący scenariusz:

ViewModel: FooViewModel : BaseViewModel, BarViewModel : BaseViewModel
Wyświetlenia: MainView, FooView, BarView

Teraz "wstrzyknę" widok i ustawię DataContext za pomocą DataTemplate i DataTemplateSelector. Oczywiście, mój ItemsControl ItemSource jest związany z ObservableCollection<BaseViewModel> w którym zawiera (na razie) instancję FooViewModel i a BarViewModel

Problem polega na tym, że chcę wprowadzić AlternateFooView który chcę wykorzystać to samo FooViewModel. Myślę, że stworzę kolejny DataTemplate i miej moje DataTemplateSelector zwróć go, ale musi być specjalna logikaokreśl, który DataTemplate ma powrócić (nie mogę po prostu przejść przez który jest ViewModel), a to oznacza, że ​​będę musiał mieć jakiś rodzaj właściwości lub pola w BaseViewModel. Nie wiem, czy to naprawdę dobry pomysł, ponieważ wydaje się, że wprowadzanie pola / właściwości do ViewModel, który jest używany tylko do wyboru widoku. Nie zaszkodzi to mojej jednostce testowej, ale wydaje mi się, że marnotrawstwo zawiera pole tylko po to, aby pomóc zdecydować, który widok interfejsu użytkownika wybrać. Nie sądzę, żeby to złamało MVVM, ale jestem ciekawy, czy ktoś tam ma jakieś inne lepsze pomysły - alternatywne pomysły, których nie lubię jeszcze bardziej ...

Idea nr 2:
- Włącz FooViewModel do klasy bazowej, która 2różne rozszerzenia FooViewModel (tj. BaseFooViewModel, FooViewModel, DifferentFooViewModel) .To wydaje się głupie, ponieważ nie ma żadnej różnicy między FooViewModel i DifferentFooViewModel, oprócz ich klasy.

Idea nr 3:
- Po prostu skopiuj FooViewModel i uczyń go FooViewModel2 (będzie dokładnie taki sam jak FooViewModel). Wydaje się to nawet gorsze od pomysłu # 2.


Kod próbki (oczywiście skorygowany):

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} />


Dzięki!

Odpowiedzi:

4 dla odpowiedzi № 1

Zgadzam się z krishnaaditya, że ​​to pytanienaprawdę sprowadza się do tego, co decyduje o tym, którego widoku użyć w oparciu o stan ViewModel. Ten rodzaj logiki często umieszczany jest w selektorze szablonów, który działa świetnie. Jeśli nie chcesz umieścić tej logiki w selektorze szablonów, rozważ przekazanie jej za pomocą mojego Routowany szablon wyboru podejście. Ułatwia to delegowanie logiki wyboru szablonu za pomocą zdarzenia routowanego.

Pomysł, który zaproponowałeś w swoim komentarzu na temat używaniaDataTrigger również może działać, ale to przywraca potrzebę właściwości obiektu VM, która wskazuje, który widok załadować (co powiedziałeś, że nie chcesz). Moim zdaniem, to nie musi być złe.