Alignment of WPF DataGrid header

In the previous post I described how you can wrap the text in the column header of the WPF DataGrid. In this post we are going to extend the style so is also possible to align the header text. The default alignment of the header text is left.

First we create 3 styles, one for each alignment possibility (left, center and right alignment).

<Style x:Key="LeftAlignmentColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource WrappedColumnHeaderStyle}">
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
</Style>

<Style x:Key="CenterAlignmentColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource WrappedColumnHeaderStyle}">
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>

<Style x:Key="RightAlignmentColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource WrappedColumnHeaderStyle}">
    <Setter Property="HorizontalContentAlignment" Value="Right"/>
</Style>

In the styles above we use the BasedOn property so the style is based on the WrappedColumnHeaderStyle we created in the previous post. The property HorizontalContentAligment is used for setting the alignment because in the default control template of the DataGridColumnHeader this property is used for aligning the content of the header.

In the column definitions we can set the HeaderStyle to a specific alignment style.

<DataGrid ItemsSource="{Binding }" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Long header text (alignment = left)" HeaderStyle="{StaticResource LeftAlignmentColumnHeaderStyle}" Width="50" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="Long header text (alignment = center)" HeaderStyle="{StaticResource CenterAlignmentColumnHeaderStyle}" Width="50" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="Long header text (alignment = right)" HeaderStyle="{StaticResource RightAlignmentColumnHeaderStyle}" Width="50" Binding="{Binding Name}"/>
     </DataGrid.Columns>
</DataGrid> 

As you can see in the picture below the header text is aligned.

There is one issue we have to fix. For wrapping the text we make use of a TextBlock. This TextBlock is correctly aligned but when the text is wrapped the text lines in the TextBlock are always aligned to the left within the TextBlock. To solve this we extend the WrappedColumnHeaderStyle with some data triggers which set the TextAlignment property of the TextBlock to the correct value.

<Style x:Key="WrappedColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock x:Name="TextBlock" TextWrapping="Wrap" Text="{Binding}"></TextBlock>
                <DataTemplate.Triggers>
                     <DataTrigger Binding="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridColumnHeader}}}" Value="Center">
                        <Setter TargetName="TextBlock" Property="TextAlignment" Value="Center"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridColumnHeader}}}" Value="Left">
                        <Setter TargetName="TextBlock" Property="TextAlignment" Value="Left"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridColumnHeader}}}" Value="Right">
                        <Setter TargetName="TextBlock" Property="TextAlignment" Value="Right"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

As you can see in the picture below also in case the text is wrapped the alignment for all text lines is correct.

Advertisements

Text wrapping in WPF DataGrid column header

The WPF DataGrid does not support out of the box wrapping of the text in the column headers. With a small style adjustment it’s possible to wrap the text in the header.

First we create a new style for the DataGridColumnHeader class. In this style we only set the property ContentTemplate so the orginal style is not touched. The ContentTemplate is set to a DataTemplate which contains a TextBlock. The TextWrapping property of this TextBlock is set Wrap. This way we have a column header with the header text wrapped.

<Style x:Key="WrappedColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock TextWrapping="Wrap" Text="{Binding}"></TextBlock>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

In the columns of the DataGrid we set the HeaderStyle property to the new style.

<DataGrid ItemsSource="{Binding }" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn HeaderStyle="{StaticResource WrappedColumnHeaderStyle}" Header="Long header text" Width="50" Binding="{Binding Name}"/>
    </DataGrid.Columns>
</DataGrid> 

As you can see in the picture below the header text is wrapped when the text is too long for the column width.