41

How does one enable text wrapping on all column headers of a DataGrid, without disabling the other default header functionality? Such as column resizing, sort direction indicator, etc which are needed.

Is there a way to do this?

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122

5 Answers5

48

Or don't bother with the primitives in the app.xaml file and do the following (my objects):

<DataGrid Name="WBdataGrid" AutoGenerateColumns="False" ColumnHeaderHeight="50" >
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock TextWrapping="Wrap" Text="{Binding}"></TextBlock>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.Columns> ...
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Nate
  • 751
  • 1
  • 7
  • 9
  • This seems to have the unfortunate effect of removing some of the styling my table had previously had via Material Design in XAML. – Tim Holt Jul 13 '21 at 17:36
24

I would like to enable text wrapping on all column headers of my DataGrid, without disabling the other default header functionality

You need to add the following namespace to your app.xaml file:

xmlns:primitives="clr-namespace:Microsoft.Windows.Controls.Primitives;assembly=WPFToolkit"

and then add this tag to app.xaml:

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

This will add text-wrapping to the headers of all of your DataGrids throughout your WPF application.

While we're on the subject, if you just wanted to center the text of each of your DataGrid headers, you could do this using the following style instead:

<Style TargetType="{x:Type primitives:DataGridColumnHeader}">
    <Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>

Yet I've seen so many WPF articles suggesting that you can only do this by adding TextWrapping or HorizontalAlignment on each DataGrid column individually:

<toolkit:DataGridTextColumn Binding="{Binding Path=TaxAmount}">
    <toolkit:DataGridTextColumn.HeaderTemplate >
        <DataTemplate>
            <TextBlock Text="Tax Amount" Width="90" TextWrapping="Wrap" HorizontalAlignment="Center"/>
        </DataTemplate>
    </toolkit:DataGridTextColumn.HeaderTemplate>
</toolkit:DataGridTextColumn>
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Mike Gledhill
  • 27,846
  • 7
  • 149
  • 159
  • 1
    Wow, you gave a good answer to a year-old question an hour before I looked for it. +1 – Quartermeister Jul 14 '10 at 15:01
  • 1
    I do not know why, but I tried all your code but It did not center the text? – Elisabeth Sep 26 '10 at 21:17
  • 1
    Fanastic solution. Just FYI, I had an existing ColumnHeaderStyle defined in a ResourceDictionary and simply pasted the Setter Property -to- Setter block into that. It worked like a charm and altered the appearance of all the datagrids that had that style, without requiring a reference to the primitives or WPF Toolkit. – SQLServerSteve Dec 02 '16 at 15:50
16

I added &#x0a; to the header text where I want the text to wrap. This is useful when you don't need to bind your header text to something

<DataGridTextColumn x:Name="cAccountNumber" 
                    Header="Account&#x0a; Number" 
                    Width="80" 
                    Binding="{Binding Path=AccountNumber}" />
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
DJ van Wyk
  • 531
  • 1
  • 13
  • 23
  • 2
    THANK YOU! - New to WPF from web technologies and this shouldn't be obnoxiously difficult with all these styles. Throw something inline. DONE! – Kristopher Jan 02 '20 at 15:19
10

Instead of assigning the column name directly to the DataGridColumn.Header property, I created a TextBlock containing the column name, set the TextWrapping property of the TextBlock to "Wrap" and assigned the TextBlock to the DataGridColumn.Header property. This preserves the default header functionality.

Example:

<toolkit:DataGridTextColumn Binding="{Binding Path=MyProperty}">
    <toolkit:DataGridTextColumn.Header>
        <TextBlock Text="Something Longer" TextWrapping="Wrap" />
    </toolkit:DataGridTextColumn.Header>
</toolkit:DataGridTextColumn>
davidsleeps
  • 9,393
  • 11
  • 59
  • 73
1

You could create a global Style for your column headers. Without any example mark-up I don't know the syntax, but it should look something like this:

<Style TargetType="{x:Type dg:ColumnHeader}">
    <Setter Property="TextWrapping" Value="Wrap"/>
</Style>

Since the Style is key-less, it will automatically be applied to all of your column headers. And styles will not override any locally set properties, so it won't "disable" any existing header functionality.

Charlie
  • 15,069
  • 3
  • 64
  • 70
  • 1
    Thanks for your suggestion, but I have not been able to get this approach to work. However I did find that I can get my desired result if instead of assigning a string to the DataGridColumn.Header property, I create a TextBlock containing my string and set the TextWrapping property of the text block to "Wrap". –  Aug 17 '09 at 22:29
  • what about wrapping the content no header? – Nitin Chaudhari Jul 01 '10 at 05:54