2010-09-08 11 views
9

Im MVVM-Modell (Model-View-ViewModel) sollte das ViewModel auf die Ansicht verweisen. Ich würde denken, dass es nicht sollte. Aber wie soll das folgende Szenario gehandhabt werden? Ich habe eine Ansicht, die ein Registersteuerelement als den Hauptcontainer hat, das Viewmodel für diese Ansicht implementiert einen Befehl, um dem Registersteuerelement eine neue Registerkarte hinzuzufügen. Der einfache Weg wäre, dem Ansichtsmodell zu erlauben, auf die Ansicht zu verweisen und dann in der Befehlsimplementierung, um die neue Registerkarte programmatisch der Tabsteuerung in der Ansicht hinzuzufügen. Das scheint einfach falsch zu sein. Sollte ich irgendwie die Tabcontrol an das Viewmodel binden und dann eine Data/Control-Vorlage implementieren, um die neuen Tabs hinzuzufügen. Ich hoffe, dass das für jemanden einen Sinn ergibt :)Sollte ein ViewModel in MVVM auf View verweisen?

Antwort

7

Reed und Dan decken den allgemeinen Ansatz jedoch in Bezug auf In Ihrem speziellen Fall ist TabControl ein ItemsControl und kann daher seine ItemsSource an eine Datensammlung in Ihrem ViewModel binden, die die anzuzeigenden Registerkarten darstellt. Die Benutzeroberfläche für jeden Registertyp kann dann durch eine DataTemplate dargestellt werden, die für den Datentyp eines Elements spezifisch ist (entweder mit DataType oder mit DataTemplateSelector). Sie können dann Datenelemente nach Bedarf von Ihrer VM hinzufügen oder entfernen und die Registerkarten automatisch aktualisieren lassen, ohne dass die VM etwas über das TabControl weiß.

+0

Alle anderen Antworten sind gut. Dieser deckt nur ab, was ich speziell machen möchte. Ich habe sogar eine Möglichkeit gefunden, das ausgewählte Element im Ansichtsmodell festzulegen, ohne auf die Ansicht über eine Eigenschaft in meiner VM zu verweisen, die an das lastAdded-Modell in meiner Sammlung gebunden ist. Sehr gepflegt ... – Johan

3

Ich finde, dass es oft ein hilfreicher Kompromiss ist, eine Schnittstelle auf der View verfügbar zu machen, die View-spezifische Funktionalität behandelt. Dies ist ein guter Weg, Dinge zu handhaben, die mit reinem Binden schwierig zu bewerkstelligen sind, wie das Schließen des Formulars, das Öffnen eines Dateidialogs (obwohl dies oft in einer eigenen Dienstschnittstelle erfolgt) oder die Interaktion mit Steuerelementen, die nicht gut für Daten ausgelegt sind Bindung (wie das von Ihnen bereitgestellte Beispiel)

Die Verwendung einer Schnittstelle hält das View- und ViewModel weiterhin weitgehend entkoppelt und ermöglicht es Ihnen, die spezifische IView während des Tests nachzuahmen.

10

In "reinem" MVVM sollte das ViewModel nicht wirklich auf die Ansicht verweisen. Es ist jedoch oft praktisch, eine Art Schnittstelle in der Ansicht bereitzustellen, mit der das ViewModel interagieren kann.

Allerdings habe ich festgestellt, dass ich das fast nie mehr mache. Der alternative Ansatz besteht darin, eine Art von attached property oder ein Blending-Verhalten innerhalb Ihrer View zu verwenden und es an Ihre ViewModel-Eigenschaften zu binden. Auf diese Weise können Sie die View-Logik in der Ansicht zu 100% beibehalten. Wenn Sie ein Verhalten dafür erstellen, erstellen Sie außerdem einen wiederverwendbaren-Typ, der in jeder ViewModel-> View-Interaktion verwendet werden kann. Ich bevorzuge diesen Ansatz gegenüber einer View-Logik innerhalb des ViewModels.

Um diese Technik zu demonstrieren, schrieb ich ein Beispiel für die Expression Code Gallery WindowCloseBehavior. Es zeigt, wie Sie ein Verhalten innerhalb der Ansicht verwenden können, das an die Eigenschaften im ViewModel gebunden ist, um den Lebenszyklus eines Fensters zu steuern, einschließlich der Verhinderung des Schließens usw.

0

Einer von uns fehlt etwas offensichtlich. Ihr Tab-Steuerelement ist ein ItemsControl. Sie sollten die ItemsSource Ihres Registersteuerelements an eine übernehmbare Auflistung in Ihrem Ansichtsmodell binden. Wenn Sie den Befehl in Ihrem Ansichtsmodell bearbeiten, um eine Registerkarte hinzuzufügen, fügen Sie einfach ein neues Element zu dieser Sammlung hinzu und, voila, Sie haben dem Steuerelement eine neue Registerkarte hinzugefügt.

Verwandte Themen