2013-06-04 9 views
8

Mam główny ViewModel zawierający listę przedmiotów, których używam w określonej ilości UserControls, które są wyświetlane w widoku głównym w widoku ContentControl. Obecny sposób wymiany danych między ViewModels polega na tworzeniu odniesienia do każdego z ViewModels w głównym ViewModel i jednym z głównych ViewModel w każdym UserControl. Jednak nie wiem, czy to jest właściwy sposób na zrobienie tego, ponieważ mam ViewModelLocator i oczekuję, że ta klasa będzie miała jakąś funkcjonalność do obsługi czegoś podobnego.Uzyskiwanie dostępu do właściwości w innych modelach ViewModels w MVVM Light

Czy ktoś może mi powiedzieć, czy to, co robię to OK, czy jest lepszy sposób robienia tego w świetle MVVM?

EDIT:

Znalazłem to kiedy szukałem czegoś innego, to byłoby lepsze rozwiązanie?

private ViewModelLocator locator = new ViewModelLocator(); 

A następnie za pomocą Właściwości lokalizatora, aby odwołać się do każdego ViewModel?

EDIT2:

Podobno co myślałem, że nie działa, początkowo miałam tylko odniesień w głównym ViewModel i to działało, ale gdy próbuję to w UserControls to rodzaj awarii mojej aplikacji. Obecnie próbuję możliwe rozwiązanie pierwszej edycji.

MainViewModel.cs (inne są podobne, w odniesieniu tylko do głównego ViewModel)

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; 
    } 
... 

Odpowiedz

17

Rzeczywiście można użyć ViewModelLocator. Domyślnie używa Inversion of Control Container, więc nawet jeśli utworzysz nową instancję lokalizatora, otrzymasz z kontenera to samo wystąpienie singleton viewmodels.

Klasa Locator:

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>(); 
    } 
} 

następnie z kodu można uzyskać do niego dostęp, jak

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

można dostać się z jednego i tylko wystąpienie ViewModel.

z XAML: zasobów (defaultly jest w Application.Resources w App.xaml)

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

i DataContext dla widoków (zarówno sterowania użytkownika lub Windows lub cokolwiek)

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

Tak, masz rację, właśnie to przetestowałem i działa tak, jak powinno, dzięki za szczegółowe rozwiązanie, jest to bardzo cenne! :) – Kryptoxx

+0

Cieszę się, że pomogło :). I możesz oczywiście użyć bardziej wyrafinowanego kontenera IOC, który pozwala ci robić o wiele więcej trików niż singletonowe modele widokowe i iniekcję zależną od konstruktora. Proste IOC jest po prostu proste ... – eMko

1

Jeśli wszystko potrzebujesz powiązać właściwość z głównego widoku, a wewnątrz kontroli treści, użyj następującej składni:

... Binding="{DataContext.mainvmpropertyname, ElementName=xxxx}" 

gdzie xxxx to nazwa dołączona do formantu treści (lub dowolnego formantu, którego głównym obiektem jest Kontekst danych). Alternatywnie możesz użyć względnego wiązania zamiast nazwy elementu.

1

Można uzyskać dostęp do właściwości publiczne ViewModel Locator programowo przez coraz Locator ze środków Apps:

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

lub tworząc kolejną instancję statyczne w klasie ViewModelLocator:

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

    static ViewModelLocator(){ ... } 

    public MainViewModel Main 
    { 
    ... 
    } 
} 

Similar Thread

Powiązane problemy