ItemsControl vs ListBox vs ListView in WPF
I wanted to highlight some of the similarities and some of the differences of ListBox vs ItemsControl.
Similarites of ItemsControl, ListBox, and ListView
These two controls are similar in a few ways.
- All three are lists
- All three support binding ItemsSource to a list
- All three are ItemsControl objects as ListBox and ListView are descendants
Differences between ItemsControl, ListBox, and ListView
Inheritence
ItemsControl
ItemsControl uses an ItemsPresenter to present its children.
System.Object
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.ItemsControl
ListBox
A ListBox is an ItemsControl but an ItemsControl is not a list box. Notice a list box is a descendant of ItemsControl but has a Selector object, which is abstract, that it specifically derives from. Inheriting from Selector provides ListBox with selection events and selection features that are missing from ItemsControl. ListBox adds a SelectionMode Dependency Property that allows for selection types of Single, Multiple, or Extended, which are defined in a SelectionMode enum. It uses ListBoxItem as its default child.
…
System.Windows.Controls.ItemsControl
System.Windows.Controls.Primitives.Selector
System.Windows.Controls.ListBox
ListView
ListView inherits from ListBox, so it is everything a ListBox is plus it has a View Dependency Property and some functions supporting the View Dependency Property. It uses ListViewItem as its default child.
…
System.Windows.Controls.ItemsControl
System.Windows.Controls.Primitives.Selector
System.Windows.Controls.ListBox
System.Windows.Controls.ListView
Sizing and Scrolling
- ItemsControl takes as much space as it needs for its child elements, which can cause it to be larger than the screen. Because its size is based on its child controls, ItemsControl does not resize when re-sizing the screen.
- ListBox and ListView take up all the space available to them from the parent and no more. Because the size is based on the parent control size, ListBox and ListView resize with the screen.
- ItemsControl does not have a ScrollBar.
- ListBox has both a vertical and horizontal ScrollBar.
Styles and Templates
Note: These default styles are obtained using Expresion Blend by right-clicking a Control and choosing Edit Template | Edit a copy.
ItemsControl Default Style
This style is short and simple.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style x:Key="ItemsControlDefaultStyle" TargetType="{x:Type ItemsControl}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ItemsControl}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"> <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- Resource dictionary entries should be defined here. --> </ResourceDictionary>
ListBox and ListView Default Style
ListBox and ListView have the same default style, with the only exception being the the TargetType, which is of course ListBox or ListView repectively.
Both have all the elements ItemsControl has, but also there are more Setters as Setters exist for the ScrollViewer and for the Border. ListBox and ListView styles also include a ScrollViewer in the ControlTemplate between the Border and the ItemsPresenter. ListBox and ListView also have a ControlTemplate.Triggers section.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <SolidColorBrush x:Key="ListBorder" Color="#828790"/> <Style x:Key="ListBoxDefaultStyle" TargetType="{x:Type ListBox}"> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> <Setter Property="BorderBrush" Value="{StaticResource ListBorder}"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> <Setter Property="ScrollViewer.CanContentScroll" Value="true"/> <Setter Property="ScrollViewer.PanningMode" Value="Both"/> <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBox}"> <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="1" SnapsToDevicePixels="true"> <ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}"> <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </ScrollViewer> </Border> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> </Trigger> <Trigger Property="IsGrouping" Value="true"> <Setter Property="ScrollViewer.CanContentScroll" Value="false"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- Resource dictionary entries should be defined here. --> </ResourceDictionary>
Note: If you accidentally put ListBoxItems under ListView, the items are wrapped in a ListViewItem control which has its own margin, which will make the items move 5 pixels further to the right.
Choosing betweeen ItemsControl, ListBox, and ListView
Choosing an ItemsControl
It is pretty easy to choose between ItemsControl and either ListBox or ListView. If you do not want the ability to select a row or switch the View, use ItemsControl. Otherwise, use ListBox or ListView.
Choosing an ListBox
Also, if you need the select feature but you do not need to be able to switch the View, use ListBox.
Choosing an ListView
If you need to be able to switch the View, then choose ListView. It doesn’t matter if you need the ability to select or not.
I googled on WPF ListView and found this website. Thanks for the details describing the differences!
“All three have ListBoxItems as children”
This is incorrect!
ItemsControl – has ContentPresenter
ListBox – has ListBoxItem
ListView – has ListViewItem
Master_WPF, thanks for catching that. Obviously what I said was inaccurate. I think you are the first peer reviewer who has commented. You just improved my article and made it more accurate.
I looked back on my research and I didn’t see a member variable for ListBoxItem. I am not sure what I was getting at. I think I tested if each could accept and display the same ListBoxItem DataTemplate. I think what I was trying to say is all three can be used to display the same DataTemplate of ListBoxItems, so if that is your goal, any of the three will do. Assuming that is what I was trying to say, obviously, I expressed this poorly.
Also, saying that ItemControl uses ContentPresenter is also innacurate. It looks like it is an ItemsPresenter not a ContentPresenter.
Again, thanks for helping improve this article.
This is awesome! Having the differences in one place presented succinctly helps
beyond words. I’ve been reading the definitions for these objects for years and
never once saw what this comparison shows. Thanks again!