【问题标题】:WPF DataGrid column header sort arrow disappear after changing the source of its view collection sourceWPF DataGrid 列标题排序箭头在更改其视图集合源的源后消失
【发布时间】:2019-01-24 04:56:04
【问题描述】:

我有以下简单的代码可以重现这个问题:

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 控件中的错误还是我在这里遗漏了什么?

【问题讨论】:

    标签: c# wpf wpfdatagrid collectionviewsource


    【解决方案1】:

    您添加到视图模型中CollectionViewSourceViewSortDescriptions 不会影响您在视图中的DataGrid 控件中看到的箭头。

    您可以通过设置其SortDirection 属性以编程方式显示特定列的箭头。所以你可以做的是创建一个自定义的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 中将 &lt;DataGrid /&gt; 元素替换为 &lt;local:CustomDataGrid /&gt; 元素即可。

    【讨论】:

    • 我想,这里我们还需要重置所有其他列的排序方向。
    猜你喜欢
    • 2014-08-28
    • 2022-07-29
    • 1970-01-01
    • 2010-11-29
    • 1970-01-01
    • 2018-03-20
    • 2011-12-06
    • 2016-07-09
    • 2021-11-04
    相关资源
    最近更新 更多