WPF MVVM: Binding a different ViewModel to each TabItem?

前端 未结 5 1129
庸人自扰
庸人自扰 2020-12-28 17:22

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

\"Main

I currently

相关标签:
5条回答
  • 2020-12-28 17:32

    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).

    0 讨论(0)
  • 2020-12-28 17:32

    For people finding this page with the same question, I found a video on YouTube: WPF MVVM - Working with tab controls and tab content, by a guy from DCOM Engineering, LLC.

    It gives a very good explanation of "how to bind a different ViewModel to each TabItem", step by step, with downloadable code.

    "Learn how to create, open, and close tabs effectively using the MVVM pattern with WPF. Facilitates unit testing."

    0 讨论(0)
  • 2020-12-28 17:44
    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}"/>
    
    0 讨论(0)
  • 2020-12-28 17:51

    No sure why the selected answer is suggesting to use ObservableCollection and create a collection of tabs and then reference them by index.

    I find it more clean to do it this way:

    MainViewModel tab1= ConfigViewModel Tab2 = UserProfileViewModel

    in MainViewModel:

    private ConfigViewModels _configVM;
    public ConfigViewModels ConfigVM { get { return _configVM; } }
    
    private UserProfileViewModel _userProfileVM;
    public UserProfileViewModel UserProfileVM { get { return _userProfileVM; } }
    
    public MainViewModel(){
    
    _configVM = new ConfigViewModels();
    _userProfileVM = new UserProfileViewModel ();
    }
    

    In th XAML file:

    <TabControl>
    <TabItem DataContext="{Binding ConfigVM }" >
    <TabItem DataContext="{Binding UserProfileVM }" >
    

    I'm not sure I understand the benefit of doing this through an observable collection.

    0 讨论(0)
  • 2020-12-28 17:56

    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>
    
    0 讨论(0)
提交回复
热议问题