WPF MVVM: Binding a different ViewModel to each Ta

2019-02-03 04:54发布

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?

标签: c# wpf mvvm
3条回答
倾城 Initia
2楼-- · 2019-02-03 05:08
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}"/>
查看更多
淡お忘
3楼-- · 2019-02-03 05:30

I use a framework such as Prism, that allows you to define regions and use the RegionManager. You can then define a ContentControl as the 'ui' for the TabItem

Then you can use the RegionManager.RequestNavigate to populate a named region with a particular view (and our views import a viewmodel and set their datacontext).

查看更多
beautiful°
4楼-- · 2019-02-03 05:33

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>
查看更多
登录 后发表回答