2017-01-20 7 views
1

I haben Klassen A, B, C, DMVVM: lose Kopplung von Viewmodels

A hat einen Verweis auf E und B und auf eine Liste von C und D.

In AViewModel diese ausgesetzt sind, in einem Baum.

Die Ansicht für A sieht wie auf dem Bild aus.

enter image description here

Wenn ein Knoten angezeigt werden, um eine entsprechende Ansicht ausgewählt soll.

Es ist Viewmodel für E, B, C und D

Meine Frage ist die folgende:

Zum Beispiel E ist der ausgewählte Knoten. Ich speichere es in AViewModel als "Objekt SelectedItem". Was ist der beste Weg, um ein EViewModel in einer lose gekoppelten Weise zu erstellen, so dass ich EViewModel in AViewModel nicht verweisen möchte.

Update:

ich über eine Lösung zu denken, aber ich nie, dass in anderen Orten zu sehen:

Zum Beispiel habe ich meine POCOs nur aussetzen könnte (B, C, D, E) AViewModel. Und in XAML konnte ich das ContentControl direkt an diese Objekte binden. Mit einem Konverter könnte ich ein BViewModel haben, wenn ich an B binde und so weiter.

+0

Kannst du bitte dein Xaml posten, damit wir das Rad nicht neu erfinden müssen? – lokusking

Antwort

0

Wenn Ihre A-Ansicht die "Liste" und die ausgewählte Ansicht anzeigt, ist es vollkommen akzeptabel, die EViewModel-Referenz in AViewModel zu haben. ViewModels kann die "Reflektion" der Ansichten sein. Wenn also die A-Ansicht eine EView enthält, kann AViewModel ein EViewModel enthalten. Sie verschachteln nur Ihre Ansichtsmodelle, sodass dieselbe Baumstruktur wie in der Ansichtsebene erstellt wird.

Obendrein würde ich nicht auf E oder B verweisen, ... in AViewModel, sondern nur auf EViewModel, BViewModel, ... Also zeigt die AView-Liste keine Modellklassen, sondern ViewModel-Klassen an. Ihr SelectedItem wird als ViewModel eingegeben und Sie können den Ansichtsteil "Display" direkt an SelectedItem binden. Dann können Sie das richtige DataTemplate auf der Ansichtsebene verwenden, um die entsprechende Ansicht anzuzeigen. Hoffe, es hilft

+0

Das mache ich gerade :) Aber ich hatte immer das Gefühl, dass dies besser gemacht werden könnte. – jannagy02

1

Eine allgemeine und weithin akzeptierte Möglichkeit, zwischen Ansichtsmodellen und anderen Komponenten in einer lose gekoppelten Weise in einer MVVM-Anwendung zu kommunizieren, wäre die Verwendung eines Ereignisaggregators oder eines Boten. Bitte beachten Sie die folgenden Links für weitere Informationen.

das Ereignis Aggregator Muster Verwendung zwischen Ansicht Modelle zu kommunizieren:https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/

MVVM - Messenger und View Services in MVVM:https://msdn.microsoft.com/en-us/magazine/jj694937.aspx.

Eine andere Möglichkeit wäre, einen gemeinsamen Dienst zu nutzen, dass Sie die Ansicht Modelle mit injizieren: https://social.msdn.microsoft.com/Forums/en-US/22907a0f-d805-4195-8272-7c284b72d2ee/example-of-using-shared-services-prism?forum=wpf

ein Ereignis-Aggregator verwenden, Messenger oder Shared-Service bedeutet, dass Sie alle Verweise zwischen den Ansichtsmodellklassen entfernen können.

Anstelle der View Model Klassen, die starke gegenseitige Referenzen haben, kennt jedes View Model nur einen einzigen Event Aggregator/Messenger/Shared Service und kommuniziert nur mit diesem. Ansichtsmodell A kann eine beliebige Anzahl von Nachrichten senden, die von anderen Ansichtsmodellen abonniert werden können, um sie intern anzuhören und zu verarbeiten.

Meine Frage ist über die besten Praktiken zum Thema von einer Instanz eines Ansichtsmodell zu schaffen, ohne eine enge Kopplung mit, nicht über die Kommunikation zwischen lose gekoppelten Viewmodels

eine Instanz eines anderen View-Modell erstellen, ohne die Schaffung Eine String-Kopplung ist nicht möglich. Wenn ein Ansichtsmodell eine Instanz eines anderen Ansichtsmodells erstellt, sind diese per Definition stark gekoppelt. Um dies zu verhindern könnten Sie ein View-Modell mit einem Schnittstellentyp injizieren, die der andere View-Modell implementiert, z.B .:

public ViewModelB(IViewModelA viewModelA) 
{ 
    //... 
} 

Dann ist ViewModelB abhängig von einem Interface-Typ anstelle einer konkreten Umsetzung der ViewModelA. Es ist ein bisschen besser als so etwas wie dies zu tun, weil dann ViewModelA und ViewModelB wird es immer sein - wie oben erwähnt - stark miteinander gekoppelt:

public ViewModelB() 
{ 
    _viewModelA = new ViewModellA(); 
} 

Aber wenn Sie wirklich über lose Kopplung zwischen Ihrer Ansicht nach Modellklassen, Sie sollte die direkten Referenzen loswerden und beginnen, einen Ereignisaggregator oder einen Messenger zu verwenden, um zwischen ihnen zu kommunizieren.

+0

Meine Frage bezieht sich auf Best Practices zum Thema Erstellen einer Instanz eines ViewModels ohne eine Thift-Kopplung, nicht über die Kommunikation zwischen lose gekoppelten ViewModels. – jannagy02

+0

Das ist unmöglich. Wenn ein Ansichtsmodell eine Instanz eines anderen Ansichtsmodells erstellt, sind diese per Definition stark gekoppelt. Siehe meine bearbeitete Antwort für weitere Informationen. – mm8

+0

@ jannagy02 Verwenden Sie eine Factory-Methode und holen Sie sich eine (Instanz von) Schnittstelle zurück. Oder verwenden Sie DI-Container wie Prism - Sie fordern einen Typ (verwenden Sie Schnittstellen) und erhalten einen konkreten Typ zurück. Aber für das, was Sie angegeben haben, klingt es wie B, C, D und E sind alle POCOs (die mit ihren eigenen Viewmodels umschlossen sein können) - AViewModel ist in der Lage, etwas über sie zu wissen, da es ihre Aufgabe ist, die Daten zu formen, zu transformieren und darzustellen die Aussicht. – slugster

Verwandte Themen