WPF DataTemplate / DataTemplateSelector — Beste Ansatz für ein ViewModel verwendet, die von 2 verschiedenen Ansichten?
Grundsätzlich, ich habe Folgendes Szenario:
ViewModel: FooViewModel : BaseViewModel
, BarViewModel : BaseViewModel
Ansichten: MainView
, FooView
, BarView
Jetzt habe ich "Spritzen" die anzeigen und festlegen der DataContext
mit DataTemplate
und DataTemplateSelector
. Natürlich, mein ItemsControl
ItemSource
gebunden ist, um eine ObservableCollection<BaseViewModel>
in die es enthält (jetzt) eine Instanz einer FooViewModel
und ein BarViewModel
Das problem ist, ich möchte ein AlternateFooView
die will ich nutzen die gleiche FooViewModel
. Ich denke, ich werde eine andere DataTemplate
und habe meine DataTemplateSelector
es zurück, aber es muss sein, spezielle Logik, um zu bestimmen, welche DataTemplate zurück (ich kann nicht einfach gehen, durch die ViewModel vorhanden ist), und das bedeutet, dass ich ' ll haben, um irgendeine Art von Eigenschaft oder ein Feld in der BaseViewModel. Ich weiß nicht, ob das wirklich eine gute Idee ist, da zu sein scheint, dass die Einführung eines Feldes/Eigenschaft in das ViewModel, dass wird nur verwendet, um eine Ansicht zu wählen. Es wird nicht weh meine unit-Tests, aber es scheint wie eine Verschwendung ein Feld enthalten, nur, um zu helfen zu entscheiden, welche UI-Ansicht zu wählen. Ich glaube nicht, dass es nicht bricht, MVVM, aber ich bin mal gespannt, ob jemand da draußen noch andere bessere Ideen? Die alternative Ideen, die ich hatte, die ich nicht mag noch mehr...
Idee #2:
- Biegen Sie FooViewModel in einer Basis-Klasse, dass 2 unterschiedliche FooViewModel erweitern (d.h. BaseFooViewModel, FooViewModel, DifferentFooViewModel). Dies scheint dumm, weil es wirklich keinen Unterschied zwischen FooViewModel und DifferentFooViewModel abgesehen von Ihrer Klasse geben.
Idee #3:
Kopieren Sie einfach FooViewModel und machen es FooViewModel2 (es werden genau identisch FooViewModel). Dies scheint sogar noch schlimmer als Idee #2.
Sample-Code (natürlich Angepasst):
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} />
Danke!
- bitte korrigieren Sie mich wenn ich bin fehlt etwas. wenn Sie verwenden möchten, AlternateFooView und FooView? Alternative items?
- Gut, ursprünglich dachte ich, dass die andere Ansicht, würde davon abhängen, was zuerst geladen in das ViewModel selbst. Ich denke, dass deine Frage tatsächlich hilft ein wenig Recht... vielleicht haben Sie einen DataTrigger auf die bestehenden DataTemplate wählen Sie die andere Ansicht anstelle von 2 verschiedenen DataTemplats?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich Stimme mit krishnaaditya, dass die Frage wirklich darauf an, was bestimmt, welche Ansicht Sie verwenden, basierend auf den Zustand des ViewModel. Diese Art von Logik ist oft in eine template-Auswahl, die Super funktioniert. Wenn Sie nicht möchten, um die Logik in dem template selector, sollten externalisieren Sie durch die Verwendung meiner Weitergeleitet Template-Auswahl Ansatz. Das macht es leicht zu delegieren, der template-Auswahl-Logik durch die Verwendung eines routed event.
Die Idee, Sie schlug in Ihrem Kommentar über die Verwendung einer DataTrigger könnte auch funktionieren, aber das führt die Notwendigkeit für ein Grundstück auf der VM-Objekt, das angibt, welche Ansicht zu laden (die Sie sagten, Sie wollen nicht). Meiner Meinung nach, das ist nicht unbedingt eine schlechte Sache.