This post is the fourth in the series of ListBox control. Here is the reference of all the posts in this series for quick reference.
Part - 6: ListBox custom ControlTemplate
Part - 4: Applying basic style to ListBox
In last 3 posts, we have learnt basic usage of ListBox control, examined some important properties of ListBox control and populating ListBox control with data (static and DataBinding). Every time we have run the application, simple ListBox control displayed items without any formatting. In this article we will look at applying some styles to ListBox control.
Controls in WPF has a default ControlTemplate applied to it which resides in Themes folder. Template is a tree of visual elements that define the look and feel of control. Hence a control consists of multiple visual elements. Every control exposes some properties that can be modified to apply basic formatting to control. Instead of modifying these properties directly on individual controls, WPF introduced a better option called Style which provides a convenient way to group control properties, modify their values and then apply style to more than one element. If you are new to concepts of Style, I would recommend you to have a look at Style Post first. To customize the look and feel of control entirely, we can create custom ControlTemplate and apply to existing control.
This post covers modifying existing properties of ListBox control and next post covers creating custom ControlTemplate for ListBox control.
Below image shows template of ListBox control with different layers in it. ListBox derives from ItemsControl so you can see one to one mapping of layers between ListBox control and ItemsControl. We can either use ItemsControl directly or we can use derived controls like ListBox, Treeview, Listview to get advantage of functionalities already implemented in these controls.
ListBox Structure (Layers)
First let’s understand briefly what each layer means and then we would customize each layer.
1. ItemsControl is framework control that can contain list of items. ListBox control derives from ItemsControl with added functionality related to ListBox. Here, we can set properties that apply directly to ListBox. When we create a new ControlTemplate, it is applied to this layer. Other layers still remain same. Template property is used to apply new ControlTemplate.
2. ItemsPanel is the layout control for organizing all items inside the control. ListBox control has VirtualizingStackPanel as its default layout control which arranges all items in vertically. We can use other layout panels like StackPanel, WrapPanel, DockPanel instead of default VirtualizingStackPanel. If we use StackPanel, items will be displayed Horizontally or Vertically. VirtualizingStackPanel is advanced StackPanel with better performance. If we use WrapPanel items will wrap Horizontally or Vertically when there is no space available. ItemsPanel property is used to apply new Panel.
3. ItemContainer is the container/wrapper for each individual data item. ListBoxItem is the default ItemContainer for ListBox control. When we DataBind ListBox to data source (.net objects) then ListBoxItem is created by default for each item. ItemContainerStyle property is used to apply new Style.
4. Actual data item: This is a simple TextBlock control that holds data item. This is the layer where we apply DataTemplate to determine what and how data is displayed for each item in ListBox. ItemTemplate property is used to apply new DataTemplate.
To get this more interesting, below is the sample of what our ListBox control would look like when we apply properties to different layers of ListBox control.
If that sounds interesting to you, follow the next post which explains how to achieve this along with code. It took a lot time for me to create above images (layer mapping) and style so if you feel this post is worth reading, please provide your comments and refer to others too.