2009-12-05 15 views
5

Sto cercando di imparare il pattern MVVM. Il problema principale che sto avendo è imparare dove dovrei dichiarare, creare e legare gli oggetti di comando.MVVM Command Binding

2 esempi:

  1. Ho una forma principale che agisce come un pulsante o di menu principale. Viene visualizzato il pulsante 1 e la vista 1, viene visualizzato il pulsante 2 e viene visualizzata la vista 2. Grande. Ora voglio tornare al modulo principale, quindi ho bisogno di un pulsante su Vista 1 (e vista 2) chiamato "Menu principale". Dove dovrei definire il comando e i gestori di comandi in modo che possa eseguire il binding al comando "ShowMainMenu"? Potrei crearli in View2ViewModel ma poi non ho accesso per mostrare la vista principale? Oppure, potrei creare thim nel modello MainView, ma poi Come faccio a legarli a loro nel modello di vista figlio (sto usando il RelayCommand obejct come per la raccomandazione di mvvm e non danno bolle al genitore.)

  2. Ho due controlli utente visibili su una singola finestra principale, chiamiamoli MainView, UC1 e UC2. ognuno di questi ha ViewModel MainViewModel, UC1ViewModel, UC2View Model. Ho un pulsante su UC1 chiamato "AddItem". Dovrebbe aggiungere un elemento in un elenco su UC2. Qual è il modo per impostare un "AddItemCommand" e collegarlo ad esso. Il comando deve essere in MainViewModel, Uc1ViewModel o UC2ViewModel? E come lo leggo ad esso.

Grazie per il vostro aiuto.

risposta

3

1) È possibile ereditare View1Model e View2Model da un ViewModel di base e definire ShowMainMenu lì.

o (è il mio approccio)

Crea RootView con ContentPresenter che mostrerà tutti i punti di vista. Crea RootVeiwModel con proprietà ViewContent. Associare il contenuto di proprietà di ContetnPresenter alla proprietà ViewContent di RootViewModel. È possibile utilizzare object come tipo di ViewContent, ma si consiglia di definire l'interfaccia supportata da MainVView1Model, View1Model e View2Model. Il cambio di ViewContent deve aumentare ProprtyChangedEvent. Definisci ShowMainViewCommand in RootViewModel che cambierà ViewContent in MainViewModel (e verrà visualizzato come MainView). Quindi associare proprietà Command di Button in View1 e View2 a quel comando, per exmple in questo modo:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RootView}}, 
         Path=DataContext.ShowMainViwe} 

V'è un certo codice di spiegare quello che sto cercando di dire:

RootView.XAML

... 
<ContentPresenter Content={Binding ViewContent} /> 
... 

RootViewModel.ca

class RootViewModel : INotifyPropertyCahnged 
{ 
    ... 
    private object _ViewContent; 
    public object ViewContent 
    { 
     get {return _ViewContent;} 
     set 
     { 
      _ViewContent = value; 
      if (PropertyChanged != null) 
      { 
       PropertyChanged ("ViewContent"); 
      } 

     } 
    } 

    private RelayCommand _ShowMainView; 
    public ICommand ShowMainView 
    { 
     get 
     { 
      if (_ShowMainView == null) 
      { 
       _ShowMainView = new RelayCommand(x => ViewContent = new MainViewModel()); 
      } 
      return _ShowMainView; 
     } 
    } 
    ... 
} 

2) Aggiungi riferimento MainViewModel a UC1ViewModel e UC2ViewModel - questo è il modo di influenzare altri controlli. MainViwModel deve contenere proprietà che contengono UC1ViewModel e UC2ViewModel Gli elementi del secondo controllo utente devono essere contenuti in ObservableCollection.

ho appena vi mostro come funziona dal codice:

class UC1ViewModel : INotifyPropertyChanged 
{ 
    ... 
    private MainViewModel _Parent; 
    public UC1ViewModel(MainViewModel parent) 
    { 
     _Panert = parent; 
    } 

    private RelayCommand _AddItemToUC2; 
    public ICommand AddItemToUC2 
    { 
     get 
     { 
      if (_AddItemToUC2 = null) 
      { 
       // UC2Content is UC2ViewModel 
       // Items is ObservableCollection 
       _AddItemToUC2 = new RelayCommand(x => _Parent.UC2Content.Items.Add(...)); 
      } 
      return AddItemToUC2; 
     } 
    } 
    ... 
} 
+0

Nel primo exmaple si imposta ViewContent = new MainViewModel()); Si suppone che questo sia un Window/Usercontrol? O hai davvero impostato il contenuto attuale su un modello di vista? – thrag

+0

È il modello di visualizzazione. Se si posiziona ContentPresenter nella propria vista e si associa la proprietà Content a ViewModel, verrà visualizzata come vista associata. Utilizzi l'associazione view-viewmodel in questo modo: bniwredyc

2

Il MainModel può avere una proprietà per ciascun UCxViewModel o, più facilmente, un elenco di ViewModels. Il comando "Mostra" creerebbe un UVxViewModel corrispondente, sottoscriverà un evento "OnClose" pubblicato da UVxViewModel e lo aggiungerà all'elenco. MainView ha un controllo (Tab Control ad esempio) associato a questo elenco e DataTemplates che definiscono le Visualizzazioni da utilizzare per ciascun UCxViewModel. Quando UVxViewModel attiva l'evento OnClose, il MainModel lo rimuove dall'elenco, causando la "visualizzazione" della vista corrispondente.

Per la parte "Aggiungi elemento", ViewModels deve condividere lo stesso elenco di elementi (il modello). UC2ViewModel può quindi aggiungere un elemento e l'UC1View verrebbe aggiornato (a condizione che l'elenco implementa INotifyCollectionChanged).

Ho trovato this explanation molto utile per comprendere MVVM.