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.
July 25, 2008 at 3:05 pm
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)