Introduction
Usually only GridView
has column headers, sure you just craft a custom control and place it above the ListView
, but in WPF, you can place the column header with small changes to the templates.
How To Do It?
GridViewHeaderRowPresenter
Take a look at ListView
Control Template in MSDN:
The GridView.GridViewScrollViewerStyleKey
is used by the ListView
’s ScrollViewer
, it has a GridViewHeaderRowPresenter
which bound to ListView.View.Columns
, although this style key is designed for GridView
, and only GridView
has Columns field, however, if I change the template so ListView
’s ScrollViewer
always style as GridViewScrollViewerStyleKey
, other View
can get the column header using similar properties.
Update Your View Derived from ViewBase
So I added the property in my VirtualWrapPanelView
:
public class VirtualWrapPanelView : ViewBase
{
...
private GridViewColumnCollection _columns = new GridViewColumnCollection();
public GridViewColumnCollection Columns
{
get { return _columns; }
}
}
To make it look better and to prevent debug message(s), you have to add a number of properties as well:
public static readonly DependencyProperty ColumnHeaderContainerStyleProperty =
GridView.ColumnHeaderContainerStyleProperty.AddOwner
(typeof(VirutalWrapPanelView));
public Style ColumnHeaderContainerStyle
{
get { return (Style)GetValue(ColumnHeaderContainerStyleProperty); }
set { SetValue(ColumnHeaderContainerStyleProperty, value); }
}
public static readonly DependencyProperty ColumnHeaderTemplateProperty =
GridView.ColumnHeaderTemplateProperty.AddOwner(typeof(VirutalWrapPanelView));
...
ColumnHeaderContainerStyle
<Style x:Key="ColumnHeaderContainerStyle" TargetType="GridViewColumnHeader">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
As its name implies, its style for the column header, I set the HorizontalContentAlignment
as Stretch
, so the header text can align in left side, while the sort indicator arrow can align in middle top.
Update ListView Template
Then you have to change the ListView
template, similar to the sample in MSDN:
<Style x:Key="{x:Type local:FileList}" TargetType="{x:Type local:FileList}" >
<...>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListView">
<Border ...>
<ScrollViewer Style="{DynamicResource
{x:Static GridView.GridViewScrollViewerStyleKey}}">
<ItemsPresenter />
</ScrollViewer>
</Border>
<..>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Update the Actual View
Then the preparation work is done, you can then update the view, using the similar way as GridView
.
<uc:VirutalWrapPanelView x:Key="SmallIconView"
ColumnHeaderContainerStyle="{StaticResource ColumnHeaderContainerStyle}" ...>
<uc:VirutalWrapPanelView.ItemTemplate>
<DataTemplate>
<..>
</DataTemplate>
</uc:VirutalWrapPanelView.ItemTemplate>
<uc:VirutalWrapPanelView.Columns>
<GridViewColumn Width="100" Header="Name"
local:FileList.SortPropertyName="sortByFullName" />
<GridViewColumn Width="100" Header="Type"
local:FileList.SortPropertyName="sortByType" />
<GridViewColumn Width="100" Header="Time"
local:FileList.SortPropertyName="sortByLastWriteTime" />
<GridViewColumn Width="100" Header="Size"
local:FileList.SortPropertyName="sortByLength" />
</uc:VirutalWrapPanelView.Columns>
</uc:VirutalWrapPanelView>
The final product can be found in my FileExplorer article (0.3).
This article has been posted on CodeProject. You can find a list of my articles here.