2014-10-06 11 views
14

ho una finestra principale con un controllo scheda contenente 2 tabItem s:MVVM WPF: associare un ViewModel diverso a ciascun TabItem?

Main Window

Al momento ho 1 ViewModel quali servizi Tab1 & Tab2. Questo ViewModel sta diventando un po 'gonfio con SOC sfocato. Voglio dividere la logica in 2 viewmodels: ViewModel 1 & ViewModel2. La mia comprensione è che è possibile impostare la Finestra principale DataContext su un Base ViewModel che contiene una collezione di ViewModels &, quindi è possibile dichiarare ogni TabItem su un ViewModel diverso.

del esempio che ho visto di questi ViewModels di base esporre un ObservableCollection in questo modo:

private ObservableCollection<ViewModel1> _viewModelCollection 
Public Observable Collection<ViewModel1> ViewModelCollection 
{ 
    get { return _viewModelCollection; } 
    set 
    { 
     _viewModelCollection = value; 
     OnPropertyChanged("ViewModelCollection"); 
    } 
} 

public BaseViewModel() 
{ 
    ViewModelCollection = new ObservableCollection<ViewModel1>(); 
    ViewModelCollection.Add(new ViewModel1(Tab1); 
    ViewModelCollection.Add(new ViewModel1(Tab2); 
} 

Ma come faccio assegnare un ViewModel diverso per ogni TabItem? Vorrei Tab1 = ViewModel1 & Tab2 = ViewModel2?

+0

Non sono sicuro che ci sia una best practice definitiva per questo. Non ti fa molto bene associare il 'ItemsSource' di' TabControl' al tuo 'ViewModelCollection', in quanto non esiste un 'template' comune (ogni tab ha presumibilmente la sua vista). Se hai un numero fisso di schede, legherei semplicemente "DataContext" di ciascuna scheda al modello di visualizzazione corrispondente e imposti il ​​contenuto di ogni scheda alla vista appropriata. Se le schede sono dinamiche, le cose diventano più complicate. –

+0

Hai provato a cercare? [1] (http://stackoverflow.com/q/14009074/1997232), [2] (http://stackoverflow.com/q/12432062/1997232), [3] (http://stackoverflow.com/ q/17952321/1997232) ... – Sinatr

+0

@Sinatr sì, ho letto quelle domande. Voglio associare a ViewModels diversi non una raccolta di istanze di differenze dello stesso ViewModel ... – Hardgraf

risposta

23

In effetti è possibile aggiungere i modelli di visualizzazione per le schede a un modello di vista principale. È quindi possibile associare i modelli di visualizzazione figlio in XAML per le schede.

Dire che si dispone di tre modelli di visualizzazione: MainViewModel, Tab1ViewModel e Tab2ViewModel. Sulla vostra MainViewModel si mantiene una raccolta di ViewModels tab:

class MainViewModel 
{ 
    ObservableCollection<object> _children; 

    public MainViewModel() 
    { 
     _children = new ObservableCollection<object>(); 
     _children.Add(new Tab1ViewModel()); 
     _children.Add(new Tab2ViewModel()); 
    } 

    public ObservableCollection<object> Children { get { return _children; } } 
} 

Dopo aver impostato il DataContext della finestra principale per il vostro MainViewModel è possibile associare la DataContext delle schede facendo riferimento alla proprietà Children:

<TabControl> 
    <TabItem DataContext="{Binding Children[0]}" x:Name="Tab1" Header="Tab1" > 
     <!-- Tab content --> 
    </TabItem> 
    <TabItem DataContext="{Binding Children[1]}" x:Name="Tab2" Header="Tab2" > 
     <!-- Tab content --> 
    </TabItem> 
</TabControl> 
+1

Brillante! esattamente quello di cui avevo bisogno, mi piace anche il binding all'indice nell'OC :) – Hardgraf

3

Uso un framework come Prism, che consente di definire le regioni e utilizzare RegionManager. È quindi possibile definire una ContentControl come il 'ui' per il TabItem

Quindi è possibile utilizzare il RegionManager.RequestNavigate per popolare una regione di nome con una vista particolare (e le nostre opinioni importare un ViewModel e impostare la loro DataContext).

+0

Sì, ho avuto un po 'di tempo con Prism. Questa app è abbastanza semplice, non pensate che valga la pena di impostare il bootstrapper ecc. – Hardgraf

+0

Suppongo di poter provare un modello base con ObservableCollection .Aggiungi un'istanza dei miei diversi ViewModels e quindi associa gli elementi della scheda alla rispettiva istanza ViewModel nella raccolta? – Hardgraf

+1

è possibile associare l'origine degli elementi dal controllo struttura a schede a un elenco di tabViewModels che verranno visualizzati nell'interfaccia utente. I TabVM possono ereditare da un BaseTabVM in cui sono presenti tutte le cose comuni e, infine, creare un modello di dati per ciascun modello di visualizzazione schede nella risorsa del progetto in modo che possano essere personalizzati individualmente. Il binding andrà in ogni singolo tabVM, si avrà un elenco di BaseTabVMs nel modello di visualizzazione della finestra principale da associare a e tutti gli elementi possono essere utilizzati in modo indipendente. –

2
class MainViewModel 
{ 
    ObservableCollection<object> _children; 

    public MainViewModel() 
    { 
     _children = new ObservableCollection<object>(); 
     _children.Add(new Tab1ViewModel()); 
     _children.Add(new Tab2ViewModel()); 
    } 

    public ObservableCollection<object> Children { get { return _children; } } 
} 

Ora in XAML associare i bambini a ItemsSource. Genera ogni scheda per ogni viewmodel che abbiamo aggiunto alla collezione osservabile

<TabControl ItemsSource="{Binding Children}"/> 
Problemi correlati