如何在更改其ItemsSource后保留DataGrid中的列排序

时间:2021-12-22 23:10:48

How can I preserve columns' sorting in DataGrid after changing its ItemsSource?

如何在更改其ItemsSource后保留DataGrid中的列排序?

The following code preserve sorting but it doesn't set column headers of DataGrid to the "sorted" state (so there's no "sorting" icon and that stuff):

以下代码保留排序但它没有将DataGrid的列标题设置为“已排序”状态(因此没有“排序”图标和那些东西):

SortDescriptionCollection sortDescriptions = new SortDescriptionCollection();
foreach (SortDescription sd in OccupationsDataGrid.Items.SortDescriptions)
{
    sortDescriptions.Add(sd);
}

OccupationsDataGrid.ItemsSource = q;

foreach (SortDescription sd in sortDescriptions)
{
    OccupationsDataGrid.Items.SortDescriptions.Add(sd);
}

1 个解决方案

#1


0  

Using Telerik's JustDecompile and looking at the DataGrid.

使用Telerik的JustDecompile并查看DataGrid。

In the static constructor for DataGrid, we have this line:

在DataGrid的静态构造函数中,我们有这一行:

ItemsControl.ItemsSourceProperty.OverrideMetadata(type, new FrameworkPropertyMetadata(null, new CoerceValueCallback(DataGrid.OnCoerceItemsSourceProperty)));

So DataGrid.OnCoerceItemsSourceProperty is called when the ItemsSource changes. It is defined as this:

因此,当ItemsSource更改时,将调用DataGrid.OnCoerceItemsSourceProperty。它被定义为:

private static object OnCoerceItemsSourceProperty(DependencyObject d, object baseValue)
{
    DataGrid dataGrid = (DataGrid)d;
    if (baseValue != dataGrid._cachedItemsSource && dataGrid._cachedItemsSource != null)
    {
        dataGrid.ClearSortDescriptionsOnItemsSourceChange();
    }
    return baseValue;
}

It ends up calling ClearSortDescriptionsOnItemsSourceChange. Which is this:

它最终调用ClearSortDescriptionsOnItemsSourceChange。这是这个:

private void ClearSortDescriptionsOnItemsSourceChange()
{
    base.Items.SortDescriptions.Clear();
    this._sortingStarted = false;
    List<int> groupingSortDescriptionIndices = this.GroupingSortDescriptionIndices;
    if (groupingSortDescriptionIndices != null)
    {
        groupingSortDescriptionIndices.Clear();
    }
    foreach (DataGridColumn column in this.Columns)
    {
        column.SortDirection = null;
    }
}

It appears that the column's SortDirection is being wiped out and that must control the appearance of the sort arrows. So... we should put it back when we add our sort descriptions back. Change the loop that re-adds the SortDescriptions to this:

看来该列的SortDirection正在被清除,并且必须控制排序箭头的外观。所以...当我们添加排序描述时,我们应该把它放回去。更改将SortDescriptions重新添加到此的循环:

foreach (SortDescription sd in sortDescriptions)
{
    OccupationsDataGrid.Items.SortDescriptions.Add(sd);
    foreach (var col in OccupationsDataGrid.Columns.Where(aa => aa.SortMemberPath == sd.PropertyName))
    {
        col.SortDirection = sd.Direction;
    }
}

#1


0  

Using Telerik's JustDecompile and looking at the DataGrid.

使用Telerik的JustDecompile并查看DataGrid。

In the static constructor for DataGrid, we have this line:

在DataGrid的静态构造函数中,我们有这一行:

ItemsControl.ItemsSourceProperty.OverrideMetadata(type, new FrameworkPropertyMetadata(null, new CoerceValueCallback(DataGrid.OnCoerceItemsSourceProperty)));

So DataGrid.OnCoerceItemsSourceProperty is called when the ItemsSource changes. It is defined as this:

因此,当ItemsSource更改时,将调用DataGrid.OnCoerceItemsSourceProperty。它被定义为:

private static object OnCoerceItemsSourceProperty(DependencyObject d, object baseValue)
{
    DataGrid dataGrid = (DataGrid)d;
    if (baseValue != dataGrid._cachedItemsSource && dataGrid._cachedItemsSource != null)
    {
        dataGrid.ClearSortDescriptionsOnItemsSourceChange();
    }
    return baseValue;
}

It ends up calling ClearSortDescriptionsOnItemsSourceChange. Which is this:

它最终调用ClearSortDescriptionsOnItemsSourceChange。这是这个:

private void ClearSortDescriptionsOnItemsSourceChange()
{
    base.Items.SortDescriptions.Clear();
    this._sortingStarted = false;
    List<int> groupingSortDescriptionIndices = this.GroupingSortDescriptionIndices;
    if (groupingSortDescriptionIndices != null)
    {
        groupingSortDescriptionIndices.Clear();
    }
    foreach (DataGridColumn column in this.Columns)
    {
        column.SortDirection = null;
    }
}

It appears that the column's SortDirection is being wiped out and that must control the appearance of the sort arrows. So... we should put it back when we add our sort descriptions back. Change the loop that re-adds the SortDescriptions to this:

看来该列的SortDirection正在被清除,并且必须控制排序箭头的外观。所以...当我们添加排序描述时,我们应该把它放回去。更改将SortDescriptions重新添加到此的循环:

foreach (SortDescription sd in sortDescriptions)
{
    OccupationsDataGrid.Items.SortDescriptions.Add(sd);
    foreach (var col in OccupationsDataGrid.Columns.Where(aa => aa.SortMemberPath == sd.PropertyName))
    {
        col.SortDirection = sd.Direction;
    }
}