Binding TabControl to ObservableCollection With Di

2019-08-28 09:43发布

问题:

'm trying to create w mainwindow that will have a tabcontrol containing multiple items ( each one is shown only on demand )... let's say we have item of type A, item of type B and item of type C I want ( using MVVM pattern) to have an observablecollection of objects that represent my tabitems and that are related to my userscontrols ( each tabitem is a usercontrol)... The problem is that i didn't figure out how to do it.

i've a tabItemViewModelBase class :

 public class TabItemViewModelBase : ViewModelBase
    {

        //Fields : 
        RelayCommand _closeCommand;


        //Constructor:
        public TabViewModel(string header)
        {
            this.Header = header;
        }

}

in my mainwindow data context, i've an observable collection of this class :

 //Propriétés
        ObservableCollection<TabViewModel> _tabItems;

In my MainWindow i've the following Tag for the TabControl Item

 <TabControl Padding="0" ItemsSource="{Binding Path=Workspaces}">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Header}"/>
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <DataTemplate>
                    **<view:ClientView/>**
                </DataTemplate>
            </TabControl.ContentTemplate>

        </TabControl>

but as you may see, all the items are attached to ClientView User control and i'm using tabviewitem to create my items, i need a property or a way to specify the content form for each element of the observablecollection...

( i've a ClientListingViewModel Class , and ClientCreationViewModel class) , and i can't use both because i don't know how to specify the view for each of them!

Thanks!

回答1:

To specify views that target specific viewmodels, you can do this in a datatemplate.

First you need to add a namespace reference to your view and viewmodel namespaces. I've included an example using a Window, but it also works for UserControls.

<Window ...
        xmlns:v="clr-namespace:PutYourViewNamespaceHere"
        xmlns:vm="clr-namespace:PutYourViewModelNamespaceHere">

Next you will need to define the datatemplates in the resources section of your container. In the example below, I'm using the ClientListingView as the datatemplate for ClientListingViewModel

<Window.Resources>
     <DataTemplate DataType="{x:Type vm:ClientListingViewModel">
          <v:ClientListingView />
     </DataTemplate>
     <DataTemplate DataType="{x:Type vm:ClientCreationViewModel">
          <v:ClientCreationView />
     </DataTemplate>
</Window.Resources>