C# WPF DataGrid Header 单击事件处理后样式未更新

C# WPF DataGrid Header Style Not Updating after On Click event handling

我有一个 C# WPF 项目使用 DataGrid 来显示 DataTable。 通过读取 CSV 文件(header 的未知数量)并使用 CSVHelper nuget 包填充它来填充 DataTable。

using (FileStream? stream = fileInfo.OpenRead())
{ 
    using (StreamReader? reader = new(stream))
    using (CsvReader? csv = new(reader, csvConfiguration))
    {
        using CsvDataReader? dr = new(csv);
        dataTable.Load(dr);
    }
}

我正在使用以下 XAML 设置显示此 DataTable。

<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>

我已将代码添加到 DataGridLoaded 事件中,循环遍历 DataGrid.Columns 中的所有 DataGridColumn 条目并将设置它们的 HeaderStyle 取决于它们是否存在于 List<string> 中:

  1. SelectedHeaderStyle
  2. UnSelectedHeaderStyle
foreach (DataGridColumn column in grid.Columns)
{
    string headerText = column.Header.ToString();
    if (cSVConfigureContext.SelectedColumns.Contains(headerText))
    {
        column.HeaderStyle = selectedHeaderStyle;
    }
    else
    {
        column.HeaderStyle = notSelectedHeaderStyle;
    }
}

我还在处理 TargetType DataGridColumnHeaderClick 事件,这将在 1 和 2 之间切换 HeaderStyle

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;
}

这部分似乎都有效。 但是,将“重置 Headers”按钮添加到 return 到一组默认的选定列,这是行不通的地方。

如果我用 DataGrid 加载 window 并按下 Reset 按钮(它运行与 中使用的代码相同的代码Loaded 事件,它工作正常。但是如果我首先单击任何 header 来切换其状态,列 header 上的样式不会改变。我看到 SelectedColumns 字符串列表,但在我关闭 window 和 re-open 一个新的 DataGrid 之前,DataGrid 中没有视觉更新。但我仍然可以单击 headers 来更改它们的状态。

我花了几个小时在谷歌上搜索强制重绘列 headers 的选项,但到目前为止没有成功。

知道为什么 Reset 按钮在 Click 事件后不起作用吗?

Any ideas why the Reset button doesn't work after a Click event?

DataGridColumnHeaderStyle 显然覆盖或优先于 DataGridHeaderStyle

在设置 [=13= 的 HeaderStyle 属性 之前,将所有 DataGridColumnHeader 元素的 Style 属性 设置为 null ] 可能会解决您的问题。