Databound Master-Detail TabControl

This is a repost

I spent the weekend trying to get a master-detail tab control working, ie with a collection bound to the TabControls Itemsource to populate the TabItems and the TabItem Content containing the detail.

Since I couldn’t find anything on the web, I’ve put together a sample.

First off define your datasource, It’s the same data I use for the RegattaManager but in xml form.

     <XmlDataProvider x:Key=”StartLineCollectionDS” XPath=”/StartLineCollection”>
      <x:XData>
        <StartLineCollection xmlns=””>
          <RaceLine>
            <ShortName>RYS (White)</ShortName>
            <RaceCollection>
              <Race>
                <RaceName>Etchells</RaceName>
                <StartTime>10:25</StartTime>
              </Race>
              <Race>
                <RaceName>RSK6 and 1720s</RaceName>
                <StartTime>10:35</StartTime>
              </Race>
              <Race>
                <RaceName>Flying Fifteen</RaceName>
                <StartTime>10:45</StartTime>  
              </Race>
            </RaceCollection>
          </RaceLine>
          <RaceLine>
            <ShortName>RYS (Black)</ShortName>
            <RaceCollection>
              <Race>
                <RaceName>IRC 0</RaceName>
                <StartTime>10:30</StartTime>
              </Race>
              <Race>
                <RaceName>IRC 1</RaceName>
                <StartTime>10:40</StartTime>                
              </Race>
              <Race>
                <RaceName>IRC 3</RaceName>
                <StartTime>10:50</StartTime>
              </Race>
            </RaceCollection>
          </RaceLine>
        </StartLineCollection>
      </x:XData>
    </XmlDataProvider>

Next define a grid for your TabControl to live in and set the Grid’s data context to be the data source

<Grid … DataContext=“{Binding Source={StaticResource StartLineCollectionDS}}”/>

Having defined the grid we can add the tab control and set it’s ItemsSource to bind to the RaceLine element.

<Grid … DataContext=”{Binding Source={StaticResource StartLineCollectionDS}}”>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width=”*”/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition/>
    </Grid.RowDefinitions>
    <TabControl … ItemsSource=“{Binding XPath=RaceLine}” />
</Grid>

Next up you need to add a DataTemplate for both the ItemsControl.ItemTemplate and the ItemsControl.ContentTemplate, the first sets up the databinding to populate the TabControl with TabItems

      <TabControl.ItemTemplate>
        <DataTemplate>
          <TextBlock Text=“{Binding XPath=ShortName}” />
        </DataTemplate>
      </TabControl.ItemTemplate>

The second defines the content for each tab.

      <TabControl.ContentTemplate>
        <DataTemplate>
          <ListBox ItemsSource=“{Binding XPath=RaceCollection/Race}” />
        </DataTemplate>
      </TabControl.ContentTemplate>

Here we have just added a list box with its ItemsSource pointing to the object you want to display.  We can add an ItemTemplate to display members from the Object.

      <TabControl.ContentTemplate>
       <DataTemplate>
         <ListBox ItemsSource=”{Binding XPath=RaceCollection/Race}” ItemTemplate=”{DynamicResource RaceCollectionTemplate}/>
       </DataTemplate>
      </TabControl.ContentTemplate>

And define it in the resources for the container…

  <Window.Resources>
    <DataTemplate x:Key=”RaceCollectionTemplate”>
      <Grid Margin=”0,0,0,3″>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width=”0.740810692573908*”/>
          <ColumnDefinition Width=”0.259189307426092*”/>
        </Grid.ColumnDefinitions>       
        <TextBlock Text=”{Binding XPath=StartTime}”/>
        <TextBlock Text=”{Binding XPath=RaceName}” />
      </Grid>      
    </DataTemplate>
  </Window.Resources>

You can quite easily extend this to show more detail from your data structure in a separate Control the same way you would normally do master-detail.

The entire code for this sample can be downloaded from http://www.quarrie.net/WPFSamples/01TabControl.zip.

Posted in WPF. 1 Comment »

One Response to “Databound Master-Detail TabControl”

  1. Fabio Says:

    What about using XML Namespaces now ?

    for instance : Instead of RaceName , Use sys:String

    ( let’s say I want to do the same thing with Ressource Dictionaries)


Leave a comment