wpfdata-bindingthemesdynamicresource

Set Dynamic DataGridTextColumn HeaderStyle


I am trying to set a dynamic header style for my DataGrid.

I can set the ColumnHeader style for the entire Datagrid, but setting the style for a single column does not work. The style is not applied to the column.

MainWindow.xaml

<Window x:Class="StyleTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <CheckBox Content="Themes" IsChecked="False" Unchecked="CheckBox_Unchecked" Checked="CheckBox_Checked" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="60,92,0,0"/>
        <DataGrid d:ItemsSource="{d:SampleData ItemCount=5}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,150,0,0" AutoGenerateColumns="False"
            ColumnHeaderStyle="{DynamicResource ColumnHeaderTest}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="SampleInt" Binding="{Binding SampleInt}"/>
                <DataGridTextColumn Header="SampleStringA" Binding="{Binding SampleStringA}"/>
                <DataGridTextColumn Header="SampleStringB" Binding="{Binding SampleStringB}" HeaderStyle="{DynamicResource ColumnHeaderTest}"/>
                <DataGridCheckBoxColumn Header="SampleBool" Binding="{Binding SampleBool, Mode=OneWay}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Linq;
using System.Windows;

namespace StyleTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            foreach (var dictionary in App.Current.Resources.MergedDictionaries.ToList())
            {
                App.Current.Resources.MergedDictionaries.Remove(dictionary);
            }
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            foreach (var dictionary in App.Current.Resources.MergedDictionaries.ToList())
            {
                App.Current.Resources.MergedDictionaries.Remove(dictionary);
            }
            App.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("pack://application:,,,/Themes/Theme1.xaml") });
        }
    }
}

/Theme/Them1.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type DataGridColumnHeader}" x:Key="ColumnHeaderTest">
        <Setter Property="Background" Value="Green"/>
    </Style>
</ResourceDictionary>

Both App.xaml, and App.xaml.cs are default with no code added.

Result

enter image description here

Here is a complete sample project demonstrating the problem.

https://www.dropbox.com/s/1t2n43gi1umkim7/StyleTest.zip?raw=1


Solution

  • The only solution I was able to come up with was to manually change the header style in code whenever the theme changes.

    private void ThemeChanged()
    {
        //a dirty hack to workaround dynamic headerstyle not working
        var CustomHeaderStyle = Application.Current.TryFindResource("CustomHeaderStyle") as Style;
        MyDataGridColumn1.HeaderStyle = CustomHeaderStyle;
    }