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.
Note: I learned that if you want to have an ItemsControl, but you want to have the scrolling. Simply make a copy of the ListBox style and change its TargetType to ItemsControl and use that style.

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.

3 Comments

  1. master_wpf says:

    “All three have ListBoxItems as children”

    This is incorrect!

    ItemsControl – has ContentPresenter
    ListBox – has ListBoxItem
    ListView – has ListViewItem

    • Rhyous says:

      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.

  2. John Barton says:

    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!

Leave a Reply

Powered by sweet Captcha