Is there a way to easily customize the DataGrid column header?
Asked Answered
R

2

12

The UWP Community Toolkit DataGrid reserves a bit of space in the column header for the sorting icon and it makes things look really strange. When you aren't using sorting (or even when a column isn't sortable), there's a 35px-wide space in the data grid column header that doesn't have anything. If you make the column width small, it cuts off your header text long before it would really need to.

I worked out a solution by getting the header after it's loaded, going down through the visual tree, and manually assigning the properties that I needed to - but it seems like a lot of work and will break if the template changes. 🤢

Is there a better way to do this?

text cut off

How I'm modifying the header now:

var mainPanel = (Windows.UI.Xaml.Controls.Grid)VisualTreeHelper.GetChild(header, 0);
if (mainPanel != null)
{
    var contentPanel = (Windows.UI.Xaml.Controls.Grid)VisualTreeHelper.GetChild(mainPanel, 1);
    contentPanel.ColumnDefinitions[1].MinWidth = 0;

    var fontIcon = (FontIcon)VisualTreeHelper.GetChild(contentPanel, 1);
    fontIcon.Margin = new Thickness(2, 0, 2, 0);
    fontIcon.SetBinding(UIElement.VisibilityProperty,//hide it instead of using opacity
        new Binding()
        {
            Source = fontIcon,
            Path = new PropertyPath(nameof(FontIcon.Opacity)),
            Converter = new ShowSortingIconValueConverter()
        });

    SetCustomizeHeader(header, false);
}
Radiant answered 17/4, 2019 at 9:54 Comment(0)
Q
3

Set the margin of DataGridColumnHeader to negative. Use a style in a ResourceDictionary like below. The -10 cuts out pre-header space, -25 post:

<Style TargetType="controlsprimitives:DataGridColumnHeader" x:Name="MyDataGridColumnHeaderStyle" x:Key="MyDataGridColumnHeaderStyle">
    <Setter Property="Margin" Value="-10,0,-25,0"/>
    <Setter Property="FontSize" Value="11"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Background" Value="LightGray"/>
</Style>

And then you obviously set your ColumnHeaderstyle = "{StaticResource MyDataGridColumnHeaderstyle"} of your DataGrid

Quartic answered 25/11, 2020 at 8:38 Comment(0)
I
1

You can define your own style for ColumnHeader (to make it and look the same as the default one, you will need to define some resources (you can take a look at the source code at GitHub)).

In the mentioned style you set FontIcon's visibility to collapsed and change MinWidth of the ColumnDefinition to 0. Should work:

<Page.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Default">
                <SolidColorBrush x:Key="InvalidBrush" Color="#FFFF00"/>
                <SolidColorBrush x:Key="FillerGridLinesBrush" Color="Transparent"/>
                <StaticResource x:Key="ScrollBarsSeparatorBackground" ResourceKey="SystemControlPageBackgroundChromeLowBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderForegroundBrush" ResourceKey="SystemControlForegroundBaseMediumBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderBackgroundColor" ResourceKey="SystemAltHighColor"/>
                <SolidColorBrush x:Key="DataGridColumnHeaderBackgroundBrush" Color="{StaticResource DataGridColumnHeaderBackgroundColor}"/>
                <StaticResource x:Key="DataGridColumnHeaderHoveredBackgroundColor" ResourceKey="SystemListLowColor"/>
                <StaticResource x:Key="DataGridColumnHeaderPressedBackgroundColor" ResourceKey="SystemListMediumColor"/>
                <StaticResource x:Key="DataGridColumnHeaderDraggedBackgroundBrush" ResourceKey="SystemControlBackgroundChromeMediumLowBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderPointerOverBrush" ResourceKey="SystemControlHighlightListLowBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderPressedBrush" ResourceKey="SystemControlHighlightListMediumBrush"/>
            </ResourceDictionary>
            <ResourceDictionary x:Key="HighContrast">
                <SolidColorBrush x:Key="InvalidBrush" Color="#FFFF00"/>
                <SolidColorBrush x:Key="FillerGridLinesBrush" Color="Transparent"/>
                <StaticResource x:Key="ScrollBarsSeparatorBackground" ResourceKey="SystemControlPageBackgroundChromeLowBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderForegroundBrush" ResourceKey="SystemControlForegroundBaseMediumBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderBackgroundColor" ResourceKey="SystemAltHighColor"/>
                <SolidColorBrush x:Key="DataGridColumnHeaderBackgroundBrush" Color="{StaticResource DataGridColumnHeaderBackgroundColor}"/>
                <StaticResource x:Key="DataGridColumnHeaderHoveredBackgroundColor" ResourceKey="SystemListLowColor"/>
                <StaticResource x:Key="DataGridColumnHeaderPressedBackgroundColor" ResourceKey="SystemListMediumColor"/>
                <StaticResource x:Key="DataGridColumnHeaderDraggedBackgroundBrush" ResourceKey="SystemControlBackgroundChromeMediumLowBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderPointerOverBrush" ResourceKey="SystemControlHighlightListLowBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderPressedBrush" ResourceKey="SystemControlHighlightListMediumBrush"/>
            </ResourceDictionary>
            <ResourceDictionary x:Key="Light">
                <SolidColorBrush x:Key="InvalidBrush" Color="#C50500"/>
                <SolidColorBrush x:Key="FillerGridLinesBrush" Color="Transparent"/>
                <SolidColorBrush x:Key="ScrollBarsSeparatorBackground" Color="{StaticResource SystemChromeMediumColor}" Opacity="0.9"/>
                <StaticResource x:Key="DataGridColumnHeaderForegroundBrush" ResourceKey="SystemControlForegroundBaseMediumBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderBackgroundColor" ResourceKey="SystemAltHighColor"/>
                <SolidColorBrush x:Key="DataGridColumnHeaderBackgroundBrush" Color="{StaticResource DataGridColumnHeaderBackgroundColor}"/>
                <StaticResource x:Key="DataGridColumnHeaderHoveredBackgroundColor" ResourceKey="SystemListLowColor"/>
                <StaticResource x:Key="DataGridColumnHeaderPressedBackgroundColor" ResourceKey="SystemListMediumColor"/>
                <StaticResource x:Key="DataGridColumnHeaderDraggedBackgroundBrush" ResourceKey="SystemControlBackgroundChromeMediumLowBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderPointerOverBrush" ResourceKey="SystemControlHighlightListLowBrush"/>
                <StaticResource x:Key="DataGridColumnHeaderPressedBrush" ResourceKey="SystemControlHighlightListMediumBrush"/>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>

        <SolidColorBrush x:Key="SystemControlGridLinesBaseMediumLowBrush" Color="{StaticResource SystemBaseMediumLowColor}" Opacity="0.4"/>
        <SolidColorBrush x:Key="SystemControlRowGroupHeaderBackgroundMediumBrush" Color="{StaticResource SystemChromeMediumColor}"/>
        <SolidColorBrush x:Key="DataGridCurrencyVisualPrimaryBrush" Color="Transparent"/>

        <StaticResource x:Key="DataGridColumnHeaderForegroundBrush" ResourceKey="SystemControlForegroundBaseMediumBrush"/>
        <StaticResource x:Key="DataGridColumnHeaderBackgroundColor" ResourceKey="SystemAltHighColor"/>
        <SolidColorBrush x:Key="DataGridColumnHeaderBackgroundBrush" Color="{StaticResource DataGridColumnHeaderBackgroundColor}"/>
        <StaticResource x:Key="DataGridColumnHeaderHoveredBackgroundColor" ResourceKey="SystemListLowColor"/>
        <StaticResource x:Key="DataGridColumnHeaderPressedBackgroundColor" ResourceKey="SystemListMediumColor"/>
        <x:String x:Key="SortIconAscending">&#xE74A;</x:String>
        <x:String x:Key="SortIconDescending">&#xE74B;</x:String>
        <StaticResource x:Key="GridLinesBrush" ResourceKey="SystemControlGridLinesBaseMediumLowBrush"/>
        <StaticResource x:Key="DataGridCellFocusVisualPrimaryBrush" ResourceKey="SystemControlFocusVisualPrimaryBrush"/>
        <StaticResource x:Key="DataGridCellFocusVisualSecondaryBrush" ResourceKey="SystemControlFocusVisualSecondaryBrush"/>

        <Style x:Key="DataGridColumnHeaderNoSortStyle" TargetType="localprimitives:DataGridColumnHeader">
            <Setter Property="Foreground" Value="{ThemeResource DataGridColumnHeaderForegroundBrush}"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="IsTabStop" Value="False"/>
            <Setter Property="SeparatorBrush" Value="{ThemeResource GridLinesBrush}"/>
            <Setter Property="Padding" Value="12,0,0,0"/>
            <Setter Property="FontSize" Value="12"/>
            <Setter Property="MinHeight" Value="32"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="localprimitives:DataGridColumnHeader">
                        <Grid x:Name="ColumnHeaderRoot">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal">
                                        <Storyboard>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="{ThemeResource DataGridColumnHeaderBackgroundColor}"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="PointerOver">
                                        <Storyboard>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="{ThemeResource DataGridColumnHeaderHoveredBackgroundColor}"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="{ThemeResource DataGridColumnHeaderPressedBackgroundColor}"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Unfocused"/>
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Opacity" To="1"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="SortStates">
                                    <VisualState x:Name="Unsorted"/>
                                    <VisualState x:Name="SortAscending">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="Opacity" To="1"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SortDescending">
                                        <VisualState.Setters>
                                            <Setter Target="SortIcon.Glyph" Value="{ThemeResource SortIconDescending}"/>
                                        </VisualState.Setters>
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="Opacity" To="1"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Rectangle x:Name="BackgroundRectangle" Grid.ColumnSpan="2" Fill="{ThemeResource DataGridColumnHeaderBackgroundBrush}" Stretch="Fill"/>
                            <Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition MinWidth="0" Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                                <FontIcon x:Name="SortIcon" Grid.Column="1" FontFamily="{ThemeResource SymbolThemeFontFamily}" Foreground="{ThemeResource DataGridColumnHeaderForegroundBrush}" FontSize="12" Glyph="{ThemeResource SortIconAscending}" HorizontalAlignment="Center" Opacity="0" VerticalAlignment="Center"
                                          Visibility="Collapsed"/>
                            </Grid>
                            <Rectangle x:Name="VerticalSeparator" Grid.Column="1" Fill="{TemplateBinding SeparatorBrush}" VerticalAlignment="Stretch" Visibility="{TemplateBinding SeparatorVisibility}" Width="1"/>
                            <Grid x:Name="FocusVisual" IsHitTestVisible="False" Opacity="0">
                                <Rectangle x:Name="FocusVisualPrimary" Fill="Transparent" HorizontalAlignment="Stretch" IsHitTestVisible="False" StrokeThickness="2" Stroke="{ThemeResource DataGridCellFocusVisualPrimaryBrush}" VerticalAlignment="Stretch"/>
                                <Rectangle x:Name="FocusVisualSecondary" Fill="Transparent" HorizontalAlignment="Stretch" IsHitTestVisible="False" Margin="2" StrokeThickness="1" Stroke="{ThemeResource DataGridCellFocusVisualSecondaryBrush}" VerticalAlignment="Stretch"/>
                            </Grid>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
</Page.Resources>

Then just use it in your DataGrid:

<controls:DataGrid ColumnHeaderStyle="{StaticResource DataGridColumnHeaderNoSortStyle}" … />
Intransigeance answered 17/4, 2019 at 20:27 Comment(1)
Yeah, I saw that but didn't want to get into completely overriding the control template... There's a lot in there and then I'd have to make sure that it stays up to date if the UWP template changes at allRadiant

© 2022 - 2024 — McMap. All rights reserved.