代码之家  ›  专栏  ›  技术社区  ›  Leon Zhou

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

  •  1
  • Leon Zhou  · 技术社区  · 6 年前

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

    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 .

    _收藏2

    这是WPF中的错误吗 DataGrid 控制还是我遗漏了什么?

    1 回复  |  直到 6 年前
        1
  •  2
  •   mm8    6 年前

    这个 SortDescriptions 你添加到 View CollectionViewSource 在视图模型中不影响在 DataGrid 视图中的控件。

    可以通过设置特定列的箭头 SortDirection 数据网格

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

    然后你只需更换你的 <DataGrid /> 元素 <local:CustomDataGrid />