I have a C# WPF project using a DataGrid to display a DataTable.
The DataTable was populated by reading in a CSV file (unknown number of headers) and populating it using the CSVHelper nuget package.
using (FileStream? stream = fileInfo.OpenRead())
{
using (StreamReader? reader = new(stream))
using (CsvReader? csv = new(reader, csvConfiguration))
{
using CsvDataReader? dr = new(csv);
dataTable.Load(dr);
}
}
I am displaying this DataTable using the following XAML setup.
<DataGrid x:Name="DataGrid"
ItemsSource="{Binding Data, UpdateSourceTrigger=PropertyChanged}"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible"
AlternatingRowBackground="AliceBlue"
AlternationCount="2"
CanUserSortColumns="False"
AutoGeneratingColumn="Data_AutoGeneratingColumn"
IsReadOnly="True"
CanUserReorderColumns="False"
Loaded="Data_Loaded"
>
<DataGrid.ColumnHeaderStyle>
<Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="DataGridColumnHeader">
<EventSetter Event="Click" Handler="DataGridColumnHeader_Click"/>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
I have added code to the Loaded Event for the DataGrid that cycles through all the DataGridColumn entries from DataGrid.Columns and will set their HeaderStyle depending on if they exist in a List<string> to either:
- SelectedHeaderStyle
- UnSelectedHeaderStyle
foreach (DataGridColumn column in grid.Columns)
{
string headerText = column.Header.ToString();
if (cSVConfigureContext.SelectedColumns.Contains(headerText))
{
column.HeaderStyle = selectedHeaderStyle;
}
else
{
column.HeaderStyle = notSelectedHeaderStyle;
}
}
I am also handling the Click event for TargetType DataGridColumnHeader which will toggle the HeaderStyle between 1 and 2.
private void DataGridColumnHeader_Click(object sender, RoutedEventArgs e)
{
var columnHeader = sender as DataGridColumnHeader;
if (columnHeader != null)
{
string headerText = columnHeader.Content.ToString();
if (cSVConfigureContext.SelectedColumns.Contains(headerText))
{
columnHeader.Style = notSelectedHeaderStyle;
cSVConfigureContext.SelectedColumns.Remove(headerText);
}
else
{
columnHeader.Style = selectedHeaderStyle;
cSVConfigureContext.SelectedColumns.Add(headerText);
}
}
e.Handled = true;
}

This part all seems to work. However, adding a "Reset Headers" button to return to a default set of selected columns, is where things are not working.
If I load the window with the DataGrid and press the Reset button (which runs the same code used in the Loaded event, it works fine. But if I first click on any header to switch its state, the style on the column header does not change. I see the change in the SelectedColumns list of strings but no visual update in the DataGrid until I close that window and re-open a new DataGrid. But I can still click headers to change their state.
I've spent a couple hours googling options for forcing a redraw of the column headers but so far no luck.
Any ideas why the Reset button doesn't work after a Click event?