Change colour of column header in WPF datagrid with autogenerated columns at runtime

13,332

this won't work like this. There are many reasons for that.

  1. you're putting a BRUSH on DataGridColumn.HeaderStringFormatProperty >> this will not work.
  2. this will not be transfered to the column's header anyway.

to be able to do this, you'll need to understand that the DataGridColumnHeader's dataContext is NOT set to be the corresponding column by default. You have to set it up manually.

have a look at this post: https://stackoverflow.com/a/5249223/479384

now as far as you are concerned, I'd do something in the same manner as in the above mentionned link:

add the dependency properties you need in your DataGridColumn's class:

private static readonly DependencyProperty ColumnHeaderTextProperty = DependencyProperty.Register("ColumnHeader", typeof(string), typeof(MyDataGridColumn));
public string ColumnHeaderText
{
    get { return (string)(GetValue(ColumnHeaderTextProperty)); }
    set { SetValue(ColumnHeaderTextProperty, value); }
}

private static readonly DependencyProperty ColumnHeaderBackgroundProperty = DependencyProperty.Register("ColumnHeader", typeof(Brush), typeof(MyDataGridColumn));
public Brush ColumnHeaderBackground
{
    get { return (Brush)(GetValue(ColumnHeaderBackgroundProperty )); }
    set { SetValue(ColumnHeaderBackgroundProperty , value); }
}

then set up the dataContext in your column's constructor like this:

public MyDataGridColumn()
{
    Header = this;
    ColumnHeaderText = "My header text";
}

(instead of the Header = "my header text"; that you had previously)

and finally, update your header template:

<DataGrid.ColumnHeaderStyle>
    <Style TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <TextBlock Text="{Binding ColumnHeaderText}" Foreground="Blue" Background="{Binding ColumnHeaderBackground}">
                        <TextBlock.LayoutTransform>
                            <RotateTransform Angle="-90" />
                        </TextBlock.LayoutTransform>
                    </TextBlock>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.ColumnHeaderStyle>

then, in your code behind, when you want to change the header's background, just do:

((MyDataGridColumn)(this.dgSkillsMatrix.Columns[4])).ColumnHeaderBackground = Brushes.Red;

EDIT: if you don't have a special class for your columns, you should be able to do this with attached properties, and you can always put the code I wrote in the constructor somewhere else like this:

myColumn.Header = myColumn;
myColumn.SetValue(columnHelper.ColumnHeaderTextProperty, "my Header Text");
myColumn.SetValue(columnHelper.ColumnHeaderBackgroundProperty, Brushes.Red);

edit for hashlock ^^

Share:
13,332
Mark McGookin
Author by

Mark McGookin

Software Developer, dealing with DataMigration, Cloud Computing, Dynamics CRM and a bit of Mobile.

Updated on June 05, 2022

Comments

  • Mark McGookin
    Mark McGookin almost 2 years

    I have a WPF DataGrid in a WPF Project Window. I have populated the grid with a DataTable, and autogenerated the columns (unfortunately a necessity) and have a requirement to change the header colour of the columns dependant on certain other factors.

    I have a list of the column names that need to be highlighted, and would easily be able to figure out their indexes based on this (as I generated them myself in the DataGrid).

    However, I can't seem to get the column header to change colour, this has to be done in the code as I don't know at design time which columns will need highlighted. I already have a bit of a template on the header ... not sure if that is "overriding" what I am trying to do.

    Grid:

    <DataGrid FrozenColumnCount="1"  AutoGenerateColumns="True" Grid.Row="1"
        AlternationCount="2" HeadersVisibility="Column" Name="dgSkillsMatrix"
        Margin="0,0,2,1" HorizontalGridLinesBrush="White" VerticalGridLinesBrush="White"
        AlternatingRowBackground="#FFD0D0EB" RowBackground="#FFECECF5" FontSize="10.5"
        Grid.ColumnSpan="1" CellStyle="{StaticResource CellHighlighterStyle}"
        ColumnHeaderStyle="{StaticResource dataGridColumnHeader}" />
    

    Header template/style:

    <DataTemplate x:Key="RotateHeaderTemplate" >
        <TextBlock Text="{Binding}" Foreground="Blue" >
            <TextBlock.LayoutTransform>
                <RotateTransform Angle="-90" />
            </TextBlock.LayoutTransform>
        </TextBlock>
    </DataTemplate>
    

    And this is what I have tried so far to get the column header to change (called on the Window_Activated event as that is called after the constructor when the grid/WPF tree is actually built):

    Style newStyle = new System.Windows.Style()
    {
        TargetType = typeof(DataGridColumn)
    };
    
    // SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#F70F49"))
    newStyle.Setters.Add(new Setter(DataGridColumn.HeaderStringFormatProperty, new SolidColorBrush(Colors.Red)));
    this.dgSkillsMatrix.Columns[4].HeaderStyle = newStyle;
    
  • David
    David about 11 years
    :-D ok, just because you made me laugh on this Monday morning ^^