Changing the "Selected" Style of ListBox's in XAML

I use ListBox's and DataTemplates a lot to show data in different ways in WPF. One of the problems I've faced is how to change the look of the "Selected" element. All the examples I could find assumed you were not using a DataTemplate.  Luckily Chris Sells came to my rescue and pointed me at the ItemContainerStyle.  Using a Template for the ListBoxItem in the ItemContainerStyle let me control the look and feel of the Selected element (or disabled items) easily.

What I wanted was a nice glow effect instead of the default blue background:

This worked fine, but I was still getting the default behavor (of coloring the background blue) when I selected an item.  To fix it, I added a Style that overrode the ListItemBox's template and replaced it with a simple border.  I added a Trigger to this template on the IsSelected to add a nice bitmap affect of a red glow.  Here's the entire XAML example:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Grid.Resources>

    <!-- The Data Source -->
    <XmlDataProvider x:Key="FolderListData">
      <x:XData>
        <People xmlns="">
          <Person Name="Chris"
                  Picture="http://www.sellsbrothers.com/services/me.jpg" />
          <Person Name="Shawn"
                  Picture="http://wildermuth.com/images/headshot.jpg" />
          <Person Name="Ian"
                  Picture="http://tinyurl.com/2szrbm" />
        </People >
      </x:XData>
    </XmlDataProvider>

    <!-- ItemContainerStyle with the Trigger for Selected -->
    <Style x:Key="RedGlowItemContainer" TargetType="{x:Type ListBoxItem}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListBoxItem}">
            <Border Background="LightGray"
                    CornerRadius="8"
                    BorderThickness="3"
                    x:Name="IconBorder"
                    Margin="8,4,8,4" >
              <ContentPresenter />
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsSelected" Value="true">
                <Setter TargetName="IconBorder" Property="BitmapEffect">
                  <Setter.Value>
                    <OuterGlowBitmapEffect GlowColor="Red" GlowSize="5" />
                  </Setter.Value>
                </Setter>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

  </Grid.Resources>

  <ListBox ItemsSource="{Binding Source={StaticResource FolderListData}, XPath=//Person}"
           HorizontalAlignment="Center"
           ItemContainerStyle="{StaticResource RedGlowItemContainer}">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel Margin="10,10,10,10"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center" >
          <Image Width="90"
                 Source="{Binding XPath=@Picture}" />
          <TextBlock HorizontalAlignment="Center"
                     VerticalAlignment="Center"
                     Height="20"
                     Text="{Binding XPath=@Name}"/>
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</Grid>

Let me know what you think...

Comments:

Thank you !!

I was doing my head in trying to do the same thing

You have saved me hours of hassle! Thanks!

Thanks for this.

When you start navigating the list box with up and down arrow you see a dotted border around the listboxitem. Is there a way to overide that property?

Thank you!!! Saved me a lot of work.

Its not obvious how to do this, so thanks for sharing

Thank you for this tip!

Thank you so much for this example.

The way I was trying to do the same thing (without the BitmapEffect) was not only wrong but much more complicated. You've saved me a headache and a half :)

Thanks for your good article


 



 
Save Cancel