Search code examples
wpflistviewexpandercollectionviewsource

WPF ListView groups repeat column headers


Is there a way to repeat the column headers inside each group of a ListView.GridView when using a grouped CollectionViewSource as the source of the ListView?

I am using the example at http://msdn.microsoft.com/en-us/library/ms754027.aspx which uses an Expander control to display each group.

I would like the column headers to appear inside the expander for each group instead of at the top of the ListView.


Solution

  • I haven't tried this, but you may be able to include GridViewHeaderRowPresenters inside your group headers:

    <GridViewHeaderRowPresenter
      DataContext="{Binding View, RelativeSource={RelativeSource FindAncestor,ListView,1}}"
      Columns="{Binding Columns}"
      ColumnHeaderContainerStyle="{Binding ColumnHeaderContainerStyle}"
      ColumnHeaderTemplate="{Binding ColumnHeaderTemplate}"
      ColumnHeaderTemplateSelector="{Binding ColumnHeaderTemplateSelector}"
      AllowsColumnReorder="{Binding AllowsColumnReorder}"
      ColumnHeaderContextMenu="{Binding ColumnHeaderContextMenu}"
      ColumnHeaderToolTip="{Binding ColumnHeaderToolTip}"
      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    

    If that doesn't work, one sure-fire way to do it is to add a Rectangle that is painted with a VisualBrush that references the one-and-only GridViewHeaderRowPresenter at the top of the GridView.

    This can be done with an attached property to be used on the Rectangle. When the attached property is set, it registers a low priority Dispatcher callback that:

    1. Scans up the visual tree to the ListView
    2. Searches down until it finds the GridViewHeaderRowPresenter
    3. Construct a VisualBrush and sets it as the Fill for the Rectangle, and

    The Rectangle itself would be something like this:

    <Rectangle HorizontalAlignment="Stretch"
               Height="{Binding Fill.Visual.RenderHeight}"
               my:GridViewHeaderHelper.SearchForHeaderRowPresenterAndSetFill="True" />