Tuesday, January 15, 2013

WPF ListBox Control Style

How to style the WPF ListBox control?

This is actually the continuation of our previous topic WPF ListBox DataTemplate. Please visit it if you're not yet finish reading it.

Below is the target style for our WPF ListBox for this blog.


Styling a WPF ListBox control is not complex and easy to understand. It only depends on you how you style it, but drilling down the template of its Style is very easy.

First we should know how to create a Style object and what properties are we going to modify. In WPF ListBox, during styling, the most important properties to modify are Style (of type Style), ItemContainerStyle (of type Style), and ItemTemplate (of type DataTemplate).

How and what is their usage?

Style: This is a basic property for FrameworkElement when styling a control.

ItemContainerStyle: This is a property for ListBox that is being used when you want to customize the style of each element.

DateTemplate: Mentioned in previous blog, this is used when you want to customize the look of the item in the ListBox (content of the Item as a DataContext). So this vary with the Data Binding.

Style for ItemContainerStyle Property

This is a very simple to implement as we are not drilling or targeting a hierarchical controls like of Grid or Calendar. This mean that you can create your own template in any control. Take a look with a XAML below as the Style for above ListBox ItermContainerStyle property.

<Style x:Key="styleListBoxItem" TargetType="{x:Type ListBoxItem}">
    <Setter Property="OverridesDefaultStyle" Value="True"></Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Grid x:Name="grid">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"></RowDefinition>
                        <RowDefinition Height="Auto"></RowDefinition>
                    </Grid.RowDefinitions>
                    <Border x:Name="hover"
                            Background="#99E7E7E7"
                            BorderBrush="#99979797"
                            BorderThickness="1"
                            CornerRadius="3"
                            HorizontalAlignment="Stretch"
                            VerticalAlignment="Stretch"
                            Visibility="Collapsed">
                    </Border>
                    <Border x:Name="highlight"
                            Background="#99B0FFA5"
                            BorderBrush="#995CB74E"
                            BorderThickness="1"
                            CornerRadius="3"
                            HorizontalAlignment="Stretch"
                            VerticalAlignment="Stretch"
                            Visibility="Collapsed">
                    </Border>
                    <ContentPresenter></ContentPresenter>
                    <Border Height="1"
                            BorderBrush="#99D7D7D7"
                            BorderThickness="0,1,0,0"
                            Grid.Row="1">
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="hover"
                                Property="Visibility"
                                Value="Visible">
                        </Setter>
                    </Trigger>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter TargetName="highlight"
                                Property="Visibility"
                                Value="Visible">
                        </Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

What the XAML written above is very simple. We only created a Style and override the default style of the ListBoxItem. After that, we created our own ControlTemplate to define the areas, texts, UI and design we're going to apply.

We then created a one Grid as the root container since the ControlTemplate cannot contain multiple children. Inside of this Grid control, we created a three Border control that will host the separator line, and highlight and hover event of the user. You will also notice that we place a ContentPresenter object, this will host as the container of the content of the ListBoxItem.

There are triggers written to listen on the events made on the UI. In the event the mouse of the user hovered above the Item in the list box, the written trigger below that checks the IsMouseOver property will command to display the Border with name "hover". In the event the mouse of the user click the item from the list, then the Border with name "highlight" will be displayed as well (trigger that checks the IsSelected property commands it).

Referencing the Styles

In the case you completed your own style for ItemContainerStyle property, then you need to create another Style that applies the ItemContanerStyle you'd created earlier into the ListBox control. Below's snippet is the sample (text with yellow background is the application).

<Style x:Key="styleListBox" TargetType="{x:Type ListBox}">
    <Setter Property="OverridesDefaultStyle" Value="True"></Setter>
    <Setter Property="ItemContainerStyle" Value="{StaticResource ResourceKey=styleListBoxItem}"></Setter>
    <Setter Property="ItemTemplate" Value="{StaticResource ResourceKey=templateListBoxItem}"></Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBox}">
                <Border BorderBrush="#5A5A5A" BorderThickness="1" CornerRadius="4">
                    <ScrollViewer Margin="1">
                        <ItemsPresenter Margin="1"></ItemsPresenter>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

You can follow WPF ListBox DateTemplate blog of how to apply the actual Style in the ListBox control.

And that's it. We just finish the blog for ListBox. Please visit other blog for your reference.

1 comment:

Place your comments and ideas