Wpf – Binding for TabItem’s content controls

data-bindingtabcontrolwpf

I have a TabControl with ItemsSource set to ObservableCollection<BookTab> and using ContentTemplateSelector to create different tabs.

class BookTab
{  
    public string Name { get; set; }  
    public string Type { get; set; }  
    public object Data { get; set; }  
}

<TabControl Name="tabControl"
            ContentTemplateSelector="{StaticResource tabTemplateSelector}">  
    <TabControl.ItemContainerStyle>  
        <Style TargetType="TabItem">  
            <Setter Property="Header" Value="{Binding Name}"/>  
            <Setter Property="Content" Value="{Binding}"/>  
        </Style>  
    </TabControl.ItemContainerStyle>  
</TabControl>

Type in BookTab determines DataTemplate used in the appropriate tab, Name is displayed on the tab header, and Data supposed to be displayed in tab's content, i.e. DataGrid.
Data is set to ObservableCollections of different types.

DataTemplate may look like this:

<DataTemplate x:Key="bookTabTemplate">  
    <TabItem Name="bookTab">  
        <Grid>  
            <DataGrid Name="bookGrid">  
                ...  
            </DataGrid>  
        </Grid>  
    </TabItem>  
</DataTemplate>

I tried different ways to bind Data property to DataGrid's ItemsSource, but all I got is grid displaying word "Book" (BookTab's Name property value).
My guess is I have to somehow propagate TabControl's binding down to DataGrid, but I cannot figure it out.

Best Answer

I would do it like this:

<TabControl SelectedItem="{Binding CurrentBook}"
          IsSynchronizedWithCurrentItem="True"
          ItemsSource="{Binding BookList}">
<TabControl.ContentTemplate>
  <DataTemplate>
     <Grid>
        <ContentControl Content="{Binding Data}"
     </Grid>
  </DataTemplate>
</TabControl.ContentTemplate>
<TabControl.ItemTemplate>
  <DataTemplate>
    <TextBlock Text="{Binding Name}"/>
  </DataTemplate>
</TabControl.ItemTemplate>
</TabControl>

... and later you define in your app.xaml how the content of your data is presented...

    <DataTemplate DataType="{x:Type viewmodel:bookviewmodel1}">
        <view:bookview1/>
    </DataTemplate>

All you have to do, is creating a view (usercontrol) for each type.

HTH

Related Topic