Changing the Data Template for the Currently Selected Item

September 28, 2008

Let’s say I have some sort of list control and I want to show or hide additional information for an item based on whether or not it is currently selected. The easiest way to do this is to create two separate DataTemplates and swap them when needed (For brevity this example just changes the color of the selected item, but this can easily be modified to show more complex information).

Typically when you create a data template for an ItemsControl you create it as a resource and set the “ItemTemplate” property like this:

<DataTemplate x:Key="ItemTemplate">
    <TextBlock Text="{Binding}" Foreground="Black"/>
</DataTemplate>
<ListBox ItemTemplate="{StaticResource ItemTemplate}" />

Behind the scenes WPF is actually wrapping each one of our TextBlocks in a ListBoxItem control. In other words, our DataTemplate get’s set as the Content of the ListBoxItem (which inherits from ContentControl). This ListBoxItem is where the IsSelected property lives that we need to get a hold of in order to swap out our data template. What we need then is to setup a trigger for the ListBoxItem when the IsSelected property changes.

<DataTemplate x:Key="ItemTemplate">
    <TextBlock Text="{Binding}" Foreground="Black"/>
</DataTemplate>
<DataTemplate x:Key="SelectedTemplate">
    <TextBlock Text="{Binding}" Foreground="White"/>
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
    <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
        </Trigger>
    </Style.Triggers>
</Style>

Now the ListBox declaration looks like this:

<ListBox ItemContainerStyle=”{StaticResource ContainerStyle}” ItemsSource=”{Binding MyData}” />

One thing to take note of here is that I am no longer setting the ItemTemplate property on the ListBox. Instead It is being set through the ContentTemplate property of the ListBoxItem. The reason is that setting it directly on the ListBox overrides the ContentTemplate property of the ListBoxItem.

Download the full code here: data-templates-example-092808. Remember to change the file extension from .doc to .zip.

kick it on DotNetKicks.com

Advertisements