Changing the Data Template for the Currently Selected Item

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

About these ads

7 Responses to Changing the Data Template for the Currently Selected Item

  1. Daniel says:

    Thanks for your help on stackoverflow!

    You forgot to rename your second DataTemplate in this blog post.

  2. micahlmartin says:

    Daniel – Thanks. I fixed it.

  3. Ben says:

    I was testing something almost identical to this example, but I changed the SelectedTemplate to use a TextBox instead because I wanted to edit the selected item (a string in this case). When the item is selected, the template changes to TextBox containing the bound text as expected. However, when I select a different item, the changes to the string are not saved back into the collection I’m using as my ItemsSource.

    VS said that I couldn’t do 2 way binding without specifying a path, so I used {Binding Path=., Mode=TwoWay} as my binding on the TextBox, which lead me to the roadblock I described above.

    Do you have any ideas? I’d like to use this with more complex templates so that I can display items nicely, but switch everything to ‘edit mode’ when the user selects an item.

  4. Ben says:

    I figured out my problem. It was so dumb: I forgot that strings are immutable, so of course the data binding couldn’t write the new value back to the string. I fixed it by wrapping the strings in my own class.

    Anyway, thanks a lot for this great templating tip! It’s exactly what I was looking for.

  5. Ant says:

    Thanks. I’d been searching for a simple example like this for a while!
    Great stuff.

  6. Parhs says:

    I tried this for Treeview and didnt work.. It seems that

    Has no effect at template at all…

  7. Anonymous says:

    I could not download the full code file

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: