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:
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?
Any ideas why the Reset button doesn't work after a Click event?
The Style
of the DataGridColumnHeader
apparently overrides or take precedence over the HeaderStyle
of the DataGrid
.
Setting the Style
property of all DataGridColumnHeader
elements to null
before setting the HeaderStyle
property of the DataGrid
will probably fix your issue.