2013-06-04 7 views
8

Ich habe eine Haupt ViewModel enthält eine Liste von Elementen, die ich in einer bestimmten Anzahl von UserControls, die in einer ContentControl in der Hauptansicht angezeigt werden. Meine derzeitige Art des Datenaustausches zwischen der ViewModels besteht darin, einen Verweis auf jeden der ViewModels in der Haupt , und einer der wichtigsten ViewModel in jedem UserControl. Allerdings weiß ich nicht, ob dies der richtige Weg ist, da ich eine ViewModelLocator habe und ich erwarte, dass diese Klasse einige Funktionen hat, um so etwas zu unterstützen.Zugriff auf Eigenschaften in anderen ViewModels in MVVM Light

Kann mir bitte jemand sagen, ob das, was ich mache, OK ist, oder ob es eine bessere Möglichkeit gibt, dies in MVVM Light zu tun?

EDIT:

ich das gefunden, wenn ich für etwas anderes gesucht wurde, wäre dies eine bessere Lösung?

private ViewModelLocator locator = new ViewModelLocator(); 

Und dann die Locator-Eigenschaften verwenden, um jedes ViewModel zu referenzieren?

EDIT2:

Offenbar was ich dachte, nicht auf den ersten nicht funktionieren würde, hatte ich nur Verweise im Haupt ViewModel und dies funktioniert, aber wenn ich versuchen, diese in der UserControls es irgendwie stürzt meine Anwendung. Ich versuche gerade die mögliche Lösung des ersten Schnitts.

MainViewModel.cs (andere sind ähnlich, nur mit Bezug auf das Hauptansichtsmodell)

public class MainViewModel : ViewModelBase 
{ 
    private ItemAddViewModel itemAddViewModel; 
    private ItemsViewModel itemsViewModel; 

    /// <summary> 
    /// Initializes a new instance of the MainViewModel class. 
    /// </summary> 
    public MainViewModel() 
    { 
     ItemsList = Item.GetItemsList(); 

     itemAddViewModel = ServiceLocator.Current.GetInstance<ItemAddViewModel>(); 
     itemsViewModel = ServiceLocator.Current.GetInstance<ItemsViewModel>(); 

     ShowItemsView(); 
    } 
... 
    private void ShowItemsView() 
    { 
     CurrentControl = itemsViewModel; 
    } 
... 

Antwort

17

Sie können den ViewModelLocator tatsächlich nutzen. Standardmäßig wird die Inversion des Steuercontainers verwendet. Wenn Sie also eine neue Instanz des Locators erstellen, erhalten Sie dieselbe Instanz von Singleton-Viewmodels aus dem Container.

Die Locator-Klasse:

static ViewModelLocator() 
{ 
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); 
    SimpleIoc.Default.Register<ViewModel1>(); 
    SimpleIoc.Default.Register<ViewModel2>(); 
    SimpleIoc.Default.Register<ViewModel3>(); 
} 

public ViewModel1 ViewModel1 
{ 
    get 
    { 
     return ServiceLocator.Current.GetInstance<ViewModel1>(); 
    } 
} 

public ViewModel2 ViewModel2 
{ 
    get 
    { 
     return ServiceLocator.Current.GetInstance<ViewModel2>(); 
    } 
} 

public ViewModel3 ViewModel3 
{ 
    get 
    { 
     return ServiceLocator.Current.GetInstance<ViewModel3>(); 
    } 
} 

dann von Code Sie darauf zugreifen können als

var vm1 = (new ViewModelLocator()).ViewModel1; 

Sie die einzige Instanz von Viewmodel bekommen.

von XAML: Ressourcen (defaultly ist in Application.Resources in App.xaml)

<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" /> 

und Datacontext für Ansichten (entweder Bedienelemente oder Fenster oder was auch immer)

<UserControl 
    ... 
    DataContext="{Binding ViewModel1, Source={StaticResource Locator}}" 
    ... > 
+0

Ja, Sie haben recht, ich habe es gerade getestet und es funktioniert wie es sollte, danke für die detaillierte Lösung, es ist sehr geschätzt! :) – Kryptoxx

+0

Ich bin froh, dass es geholfen hat :). Und Sie können natürlich einen ausgefeilteren IOC-Container verwenden, mit dem Sie viel mehr Tricks machen können als Singleton Viewmodels und Konstruktorabhängigkeits-Injection. Einfaches IOC ist einfach ... – eMko

1

Wenn alle Sie müssen eine Eigenschaft aus dem Hauptansichtsmodell binden, während Sie im Inhaltssteuerelement nur diese Syntax verwenden:

Dabei steht xxxx für den Namen, der an das Inhaltssteuerelement angehängt ist (oder an ein beliebiges Steuerelement, dessen Hauptansichtsmodell DataContext ist). Alternativ können Sie die relative Bindung anstelle des Elementnamens verwenden.

1

Sie könnten die öffentlichen Eigenschaften des Ansichtsmodell Locator zugreifen programmatisch durch den Locator aus den Apps Ressourcen bekommen:

MyViewModel vm = (App.Current.Resources["Locator"] as ViewModelLocator).MyViewModel 

oder eine andere statische Instanz in der ViewModelLocator Klasse erstellen:

public class ViewModelLocator 
{ 
    public static ViewModelLocator Instance = new ViewModelLocator(); 

    static ViewModelLocator(){ ... } 

    public MainViewModel Main 
    { 
    ... 
    } 
} 

Similar Thread

Verwandte Themen