В основном, у меня есть следующий сценарий:
ViewModel: FooViewModel : BaseViewModel
, BarViewModel : BaseViewModel
Просмотров: MainView
, FooView
, BarView
Прямо сейчас я «внедряю» вид и устанавливаю DataContext
, используя DataTemplate
и DataTemplateSelector
. Очевидно, что мой ItemsControl
ItemSource
связан с ObservableCollection<BaseViewModel>
, в котором он содержит (на данный момент) экземпляр FooViewModel
и BarViewModel
Проблема в том, что я хочу ввести AlternateFooView
, который я хочу использовать тот же FooViewModel
. Я полагаю, что создам еще один DataTemplate
, и мой DataTemplateSelector
вернет его, но должна быть специальная логика, чтобы определить, какой DataTemplate нужно вернуть (я не могу просто определить, какая ViewModel там есть), и это означает, что я Вам нужно будет иметь некоторый тип свойства или поля в BaseViewModel. Я не знаю, действительно ли это хорошая идея, потому что кажется, что в ViewModel вводится поле / свойство, которое используется только для выбора вида. Это не повредит моему модульному тестированию, но кажется пустым, чтобы включить поле только для того, чтобы решить, какой вид интерфейса выбрать. Я не думаю, что это ломает MVVM, но мне любопытно, есть ли у кого-нибудь еще идеи получше? Альтернативные идеи, которые у меня были, мне даже больше не нравятся ...
Идея № 2:
- Превратите FooViewModel в базовый класс, который расширяют 2 разных FooViewModel (то есть BaseFooViewModel, FooViewModel, DifferentFooViewModel). Это кажется глупым, потому что на самом деле нет никакой разницы между FooViewModel и DifferentFooViewModel, кроме их типа класса.
Идея № 3:
- Просто скопируйте FooViewModel и сделайте его FooViewModel2 (он будет полностью идентичен FooViewModel). Это кажется даже хуже, чем идея № 2.
Код образца (корректируется явно):
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} />
Спасибо!