Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF MVVM: Binding a different ViewModel to each TabItem?

Tags:

I have a main window with a tab control containing 2 tabItems:

Main Window

I currently have 1 ViewModel which services Tab1 & Tab2. This ViewModel is becoming a little bloated with blurred SOC. I want to split the logic into 2 viewmodels: ViewModel 1 & ViewModel2. My understanding is that you can set the Main Window DataContext to a Base ViewModel which holds a collection of ViewModels & then you can assert each TabItem to a different ViewModel.

The example's I've seen of these base ViewModels expose an ObservableCOllection like so:

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

But how do I assign a different ViewModel to each TabItem? I would want Tab1= ViewModel1 & Tab2=ViewModel2?

like image 906
Hardgraf Avatar asked Oct 06 '14 14:10

Hardgraf


2 Answers

You can indeed add the view models for your tabs to a main view model. You can then bind to the child view models in the XAML for your tabs.

Say that you have three viewmodels: MainViewModel, Tab1ViewModel, and Tab2ViewModel. On your MainViewModel you keep a collection of your tab viewmodels:

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

After setting the DataContext of your main window to your MainViewModel you can bind the DataContext of your tabs by referencing the Children property:

<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>
like image 142
Jakob Christensen Avatar answered Oct 06 '22 12:10

Jakob Christensen


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

Now in XAML bind the Children to ItemsSource. It will generate each Tab for every viewmodel we have added into the observable collection

    <TabControl ItemsSource="{Binding Children}"/>
like image 31
Varatharaj Avatar answered Oct 06 '22 11:10

Varatharaj