WPF DataGrid列标题排序箭头在更改其视图集合源后消失

4
我是一个有用的助手,可以为您翻译文本。
我有以下简单的代码,可以重现这个问题:
XAML:
<DataGrid ItemsSource="{Binding Source.View}"
          AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name"
                            Binding="{Binding Name}"
                            SortMemberPath="Name"
                            SortDirection="Ascending"/>
    </DataGrid.Columns>
</DataGrid>

视图模型:

private readonly ObservableCollection<Data> _collection1 = new ObservableCollection<Data> {new Data("item 1"), new Data("item 2")};
private readonly ObservableCollection<Data> _collection2 = new ObservableCollection<Data> {new Data("person 1"), new Data("person 2")};

public MainViewModel()
{
    Source.Source = _collection1;

    // Set up a timer that runs 5 seconds.
    Observable.Timer(TimeSpan.FromSeconds(5)).ObserveOn(AsyncOperationManager.SynchronizationContext).Subscribe(_ =>
    {
        // Get existing sort descriptions.
        var existingSortDescription = Source.View.SortDescriptions.ToList();

        // Change source.
        Source.Source = _collection2;

        // This has to be done in order to maintain the sort order.
        existingSortDescription.ForEach(Source.SortDescriptions.Add);
    });
}

public CollectionViewSource Source { get; } = new CollectionViewSource();

private class Data
{
    public Data(string name)
    {
        Name = name;
    }

    public string Name { get; }
}

上述代码的作用是,在应用程序启动时,首先使用_collection1作为数据网格中项源的来源。
5秒后,将数据网格的项源更改为_collection2
如果运行上述代码,则当源更改为_collection2时,“名称”列标题中的排序方向箭头将消失,但排序仍然正确。
这是否是WPF DataGrid控件中的错误,还是我在这里漏掉了什么?
1个回答

4
您在视图模型中添加到 CollectionViewSource 的 View 中的 SortDescriptions 不会影响您在视图中看到的 DataGrid 控件中的箭头。 您可以通过设置其 SortDirection 属性来以编程方式显示特定列的箭头。 因此,您可以创建一个自定义的 DataGrid 控件来为您处理此操作(内置的 DataGrid 控件无法实现此操作),例如:
public class CustomDataGrid : DataGrid
{
    protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
    {
        base.OnItemsSourceChanged(oldValue, newValue);

        INotifyCollectionChanged oldView = oldValue as INotifyCollectionChanged;
        if (oldView != null)
            oldView.CollectionChanged -= View_CollectionChanged;

        INotifyCollectionChanged newView = newValue as INotifyCollectionChanged;
        if (newView != null)
            newView.CollectionChanged += View_CollectionChanged;
    }

    private void View_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        ICollectionView view = sender as ICollectionView;
        if (view != null)
        {
            SortDescription sd = view.SortDescriptions.LastOrDefault();
            if (sd != null)
            {
                DataGridColumn column = Columns.FirstOrDefault(x => x.SortMemberPath == sd.PropertyName);
                if (column != null)
                {
                    column.SortDirection = sd.Direction;
                }
            }
        }
    }
}

接下来,您只需在 XAML 中将 <DataGrid /> 元素替换为 <local:CustomDataGrid /> 元素即可。


我认为,在这里我们还需要重置所有其他列的排序方向。 - Arsen Khachaturyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接