Essential WPF ListBox Styling

This article explains how to style a WPF ListBox. I know: there must be a million articles about this subject. So if you're looking for kaleidoscopic brushes, dazzling effects, and animations from outer space, then feel free to press the Back button in your browser to return to your search engine page, and click the next hit. If however you're interested in some details on how to put the cherry on the templated ListBox cake, then please continue reading.

 

Styling the content

The first step in styling any list control is creating a data template for the list items. So let's get it over with.

A simple data template

The list control will be populated with objects with properties (obviously, because there's nothing else in .NET ;-). The following data template displays the name property of its source. The DataType property in the XAML is mandatory and then ignored.

<DataTemplate

   x:Key="RockstarTemplate"

   DataType="Whatever">

    <Border

       x:Name="TheBorder"

       BorderBrush="Gray"

       BorderThickness="1"

       Padding="4"

       CornerRadius="4"

       Margin="2">

        <TextBlock

           Text="{Binding Name}"

           Width="320">

        </TextBlock>

        <Border.Background>

            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">

                <GradientStop Color="AliceBlue" Offset="0.15" />

                <GradientStop Color="White" Offset="0.85" />

                <GradientStop Color="Lavender" Offset="1" />

            </LinearGradientBrush>

        </Border.Background>

    </Border>

</DataTemplate>

 

Styling the selected items

The selected items deserve to be highlighted, so we define an extra brush for these:

<LinearGradientBrush

   x:Key="SelectedItemBrush"

   EndPoint="0.5,1" StartPoint="0.5,0">

    <GradientStop Color="Lavender" Offset="0.15" />

    <GradientStop Color="AliceBlue" Offset="0.85" />

    <GradientStop Color="CadetBlue" Offset="1" />

</LinearGradientBrush>

The following code applies the brush through a data trigger. The XAML is quite complex, but very clear. We walk up the visual tree to discover the parent list box item, and apply the brush if it IsSelected:

<DataTemplate.Triggers>

    <DataTrigger

       Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}"

       Value="True">

        <Setter

           TargetName="TheBorder"

           Property="Background"

           Value="{StaticResource SelectedItemBrush}" />

    </DataTrigger>

</DataTemplate.Triggers>

This is as far as I will go regarding data templates. Check out the WPF Themes at CodePlex for some good in-depth data template examples.

Apply the template

Here's how to apply the template to a listbox:

<ListBox

   x:Name="ItemTemplateBox"

   ItemTemplate="{StaticResource RockstarTemplate}"

   BorderBrush="Transparent"

   Background="Transparent"           

   />

 

Styling the listbox itself

A data template is not enough

Creating the data template is the fun part. Here is were most blog and other articles end - leaving you in frustration. Because just applying a data template to style a listbox's items is not sufficient to provide a nice user experience. Here's how the current listbox -with just a data template- looks like when running the application:

Even when the focus went to another control, the data-template-only listbox shows unwanted side effects:

Actually, some important looks of the selected list item(s) are not defined in the data template itself, including:

  • the (blue) background color,
  • the (white) foreground color, and
  • the dotted border to express keyboard focus.

While it's possible to improve the looks by tweaking the data template (e.g. by using negative padding), the right place to style these settings is the parent listbox itself.

Where are the original control templates?

The XAML resource dictionaries for the builtin themes (Classic, Aero, ...) can be found here at MSDN (4.0 versions apparently are not yet available). The source code of the themes also come with Expression Blend (search for the SystemThemes folder), and can be found in a lot of other places. If you open one of these files and search for the ListBoxItem styles, you'll find stuf like this:

<Setter Property="Padding"

       Value="2,0,0,0"/>

This code is responsible for that horrible thin blue line on the left side of your data template.

In the default XAML template for ListBoxItem you'll also find this trigger:

<Trigger Property="IsSelected"

           Value="true">

    <Setter TargetName="Bd"

           Property="Background"

           Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>

    <Setter Property="Foreground"

           Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>

</Trigger>

Here's where the blue background and the white text color comes from.

Overriding default brushes

Instead of redefining the whole ListBoxItem style, you can easily get away with overriding the brushes that are used as static resource. You can use the following XAML to make the unwanted stylings disappear:

<ListBox.Resources>

    <!-- Style used if item is selected and listbox has keyboard focus -->

    <Style x:Key="NoFocusVisualStyle" TargetType="Control">

        <Setter Property="BorderBrush" Value="Transparent" />

    </Style>

    <!-- Apply this style -->

    <Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem">

        <Setter Property="FocusVisualStyle" Value="{StaticResource NoFocusVisualStyle}" />

    </Style>

    <!-- Color used if item is selected and listbox has focus -->

    <SolidColorBrush

       x:Key="{x:Static SystemColors.HighlightBrushKey}"

       Color="Transparent"/>

    <!-- Color used if item is selected and listbox does not have focus -->

    <SolidColorBrush

       x:Key="{x:Static SystemColors.ControlBrushKey}"

       Color="Transparent"/>

    <!-- Font color used if item is selected and listbox has focus -->

    <SolidColorBrush

       x:Key="{x:Static SystemColors.HighlightTextBrushKey}" 

       Color="Black" />

</ListBox.Resources>

 

Empty data

Unfortunately WPF controls don't have an EmptyDataTemplate property like their ASP.NET siblings. The empty data template describes how the list control looks like when it's bound to an empty data source.

In WPF we have to build this ourselves. Let's keep things simple and display a TextBox in front of the ListBox, and bind its visibility to the items count of the ListBox.

Here's the XAML:

<Grid>

    <ListBox

    ...

    </ListBox>

    <TextBlock

       Margin="4"

       FontStyle="Italic"

       Text="No data found..."

       Grid.Row="0" Grid.Column="1" Grid.RowSpan="2">

        <TextBlock.Style>

            <Style TargetType="{x:Type TextBlock}">

                <Setter Property="Visibility" Value="Collapsed" />

                <Style.Triggers>

                    <DataTrigger Binding="{Binding ElementName=EmptyTemplateBox, Path=Items.Count}" Value="0">

                        <Setter Property="Visibility" Value="Visible" />

                    </DataTrigger>  

                </Style.Triggers>

            </Style>                            

        </TextBlock.Style>

    </TextBlock>

</Grid>

Here's how it looks like when the app runs: 

Source Code

As usual, here's a working sample: U2UConsult.WPF.Template.Sample.zip (17,81 kb)

Enjoy!


May 16. 2012 09:06 PM

Anze Kopitar Jersey

Jordan lorsque michael jordan intégra le monde de la nba en 1984, ce ne fut pas seulement le début d'une carrière sans égal, mais aussi le début de la série célèbre "<a href="http://www.aj-fr.com/">Air Jordan</a>" de nike. le fabricant d'articles de sport accorda toute une série de chaussures et d'habits au basketteur doté apparemment de talents surhumain. cette série fit tout de suite sensation : l' <a href="http://www.aj-fr.com/3-air-jordan-1">Air Jordan 1</a> fut interdite par la nba puisque la combinaison des coloris noir/rouge ne correspondit pas au "code vestimentaire" de la nba à l'époque. pourtant, cela ne put empêcher le succès mondial de cette sneaker unique. au contraire : la chaussure de basket déclencha une véritable hystérie et est, dès lors, lancée dans une nouvelle édition chaque année.jordan - plus qu'une simple chaussure de basket les spots publicitaires de jordan sont aussi innovateurs que les produits eux-mêmes. au cours des années 80, avec spike lee alias mars blackmon, ils conquirent les écrans de la télé. aujourd'hui, les spots pour les différents modèles d'air jordan sont toujours de vrais classiques sur youtube. de nos jurs, le jumpman ne se porte pas seulement sur les chaussures : <a href="http://www.aj-fr.com/18-Air-Jordan">Air Jordan 3</a>, <a href="http://www.aj-fr.com/19-air-jordan-4">Air Jordan 4</a>, <a href="http://www.aj-fr.com/20-air-jordan-5">Air Jordan 5</a>, <a href="http://www.aj-fr.com/21-Air-Jordan">Air Jordan 6</a>, <a href="http://www.aj-fr.com/22-Air-Jordan">Air Jordan 7</a>, <a href="http://www.aj-fr.com/55-Other-Styles">Air Jordan Spizike</a>. ils se distinguent par le design typique de la marque et convainquent par une excellente qualité et des matières hut de gamme. en 1997, nike externalisa même la série de jordan : aujourd'hui, la marque de jordan développe ses propres produits, mais coopère néanmoins étroitement avec nike. des joueurs comme carmelo anthony ou dwyane wade portent le jumpman dans la nba. ainsi, michael jordan reste présent dans la meilleure ligue de basket-ball du monde. Obtenez les dernières <a href="www.aj-fr.com/25-air-jordan-2012">Air Jordan 2012</a> Chaussures avec style avant-gardiste et la technologie. Obtenez les dernières Chaussures Air Jordan avec style avant-gardiste et la technologie. Boutique 100% authentique <a href="http://www.aj-fr.com/">Nike Air Jordan</a> à partir des collections les plus emblématiques. <a href="http://www.aj-fr.com/">Air Jordan Retro</a>, Fusion, Hommes, Femmes et Enfants Chaussures.

Anze Kopitar Jersey

May 16. 2012 09:27 PM

sac louis vuitton

le virtuels et aux simulations de tir.(lien en anglais) pour supprimer le programme de son ordinateur.?? [url=http://www.lvpascher1.com/]sac louis vuitton[/url] "L'objectif est ainsi de prendre des parts de marché à la voiture, par rapport à laquelle l'autocar représente un moyen de transport nettement plus écologique et très sécurisé".Le candidat s'est également réjoui d'avoir irrité la gauche et les syndicats en annon? [url=http://www.lvpascher1.com/]sac vuitton[/url] Celle-ci promet en effet une machine "immunisée contre les virus". [url=http://www.lvpascher1.com/]sacs louis vuitton[/url]ler l'immigration, améliorer la sécurité, changer l'Europe pour qu'elle ne soit plus une "passoire",? Je parle aussi bien à ceux qui ont voté Fran? [url=http://www.lvpascher1.com/]louis vuitton site officiel[/url]: se faire passer pour un no life?Stora :? [url=http://www.lvpascher1.com]louis vuitton pas cher[/url]Selon Dr?

sac louis vuitton

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading

Download the U2U brochure

Download Brochure

Receive the U2U Newsletter. Submit your email address:
 
 


 


Search

rss  RSS

Tags

Archive

Blogroll