AutoSizingGridView is a class used with Microsoft WPF ListViews which automatically sizes GridViewColumns based on dynamic content. The basic GridView class already sizes itself automatically, but the sizing is done based on initial visible content. AutoSizingGridView extends this to react to new ListViewItems and, optionally, to changes in content for existing items. AutoSizingGridView manages column width, but uses the default GridView support for row height maintenance. You may find you need to tweak the code to support changes in non-text (e.g., image-based, or complex cells) data.
AutoSizingGridView
provides a convenient replacement for the default WPF GridView
class, which implements automatic column width management, based on dynamic ListView
content.
Introduction
WPF's ListView
control is a useful tool for viewing a relatively small number of records of read-only fixed-format data. The default GridView
class supplied with WPF automatically formats data into rows and columns, calculating the row height and column width based on the initial set of visible rows. This is sufficient for most cases, but can be limiting if the data is dynamic -- when new rows are added over time or the contents of visible records changes. The changed data values are displayed as truncated values when they don't fit into the existing column. The user can manually resize the columns to see the new data, but this may be inconvenient. Replacing the GridView
class with AutoSizingGridView
is an easy way to reduce the need for manually resizing ListView
columns.
Using AutoSizingGridView
The AutoSizingGridView
class is a drop-in replacement for WPF's GridView
class. It's used as the View
property of the ListView
class:
<ListView x:Name="AutoSizedListView" SelectionMode="Extended"
ItemsSource="{Binding RelativeSource=
{RelativeSource AncestorType=local:MainWindow}, Path=Items}">
<ListView.View>
<asgv:AutoSizingGridView x:Name="AutoSizedGridView" IsValueTrackingEnabled="True">
<GridViewColumn Header="Name"
DisplayMemberBinding="{Binding Name, NotifyOnTargetUpdated=True}" />
<GridViewColumn Header="Description"
DisplayMemberBinding="{Binding Description}" />
</asgv:AutoSizingGridView>
</ListView.View>
</ListView>
The only new property is the IsValueTrackingEnabled
property, which determines if the <code>AutoSavingGridView
will re-size when the contents of existing items is displayed (true
). Setting the IsValueTrackingEnabled
property to False
inhibits value-change monitoring. Changed item values may still be displayed (as they usually are using GridView
, if the source item implements INotifyPropertyChanged), but the value could be truncated. Change tracking is relatively expensive, so the property defaults to false
.
Individual column widths can be set to be fixed, using XAML, programmatically, or manually by the user. AutoSavingGridView
will not resize columns whose width has been set. Remaining columns will continue to be auto-sized.
Demonstration Application
A simple application is supplied to demonstrate how AutoSavingGridView
and GridView
react to changes in a ListView
's items. You can use it to add items and change existing items, observing how they're displayed using both views.
Implementation
The AutoSizingGridView
class is derived from the WPF GridView
class. It overrides the GridView.PrepareItem
method to receive notification when a new ListViewItem
is ready to be displayed. An AutoSizingGridView
instance can only be the member of one ListView
's View property. Each ListView
must have a dedicated AutoSavingGridView
.
AutoSavingGridView
will monitor column headers to ensure they fit, when the IsValueTrackingEnabled
property is set to true
. A change to a GridViewColumn
's Header
property may expand the column's width to ensure the header fits. Since the AutoSizingGridView
instance doesn't become active until the first ListViewItem
is prepared, changes to column widths are delayed until the first item is prepared.
AutoSavingGridView
always checks new ListViewItem
s to ensure each cell's data can be displayed without truncation. Columns with fixed width are ignored. AutoSavingGridView
does not shrink columns -- it only expands them when needed. Thus a column may become very wide to support a long data item, and will remain wide even when the item is removed or no longer visible. When the IsValueTrackingEnabled
property is set to true
, AutoSizingGridView
also tries to track changes to individual cells in a row. If the column's DisplayMemberBinding
has set NotifyOnTargetUpdated
to true
, the item's TargetUpdated
event is hooked. Otherwise, the item's PropertyChanged
event is used for tracking changes. This should be sufficient for simple text columns, but may not be sufficient for more complex or structured data.
History
- 6th August, 2020: Initial version