WPF DataGrid MultiColumn sort without key

WPF DataGrid has a default behavior that allows you to create multi-column sorts when a user clicks on multiple column headers. Is there a way to change this behavior so that the Shift key is not required? I already handled the sort event in the datagrid, so that each column will cycle between the three sort states (Ascending, Descending and No Sort), and all this works as expected while the shift key is held down, but I would like to make it so that the DataGrid did not sort reset all other columns if the user clicks the column heading to add sorting without pressing shift.

+3
source share
2 answers

I found a solution that seems a bit hacky, but it works. In this article, I pointed in the right direction: http://blogs.msdn.com/b/vinsibal/archive/2008/08/29/wpf-datagrid-tri-state-sorting-sample.aspx?PageIndex=2 . This led me to realize that the SortDirection of each column is not tied to the SortSesource ItemsSource in any way. So, I subscribed to the Sort event in the Datagrid and reset the SortDirection of each column referenced by the CollectionSource SortDescriptions. Apparently, not pressing shift clears the sorting of each column, but does not reset SortDescriptions.

+1
source

I was dealing with the same problem, but no one showed code that could solve this. The question is old, but I hope that the solution will be useful for seekers.

(DataGrid.Items.SortDescriptions as INotifyCollectionChanged).CollectionChanged += OnGridCollectionChanged;

 private void OnGridCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
        {
            var sortingCollection = (SortDescriptionCollection)sender;
            foreach (var sortDesc in sortingCollection)
            {
                foreach (var column in SignaturesInImagingGrid.Columns)
                {
                    if (column.SortMemberPath.Equals(sortDesc.PropertyName))
                    {
                        column.SortDirection = sortDesc.Direction;
                    }
                }
            }
        }

<DataGrid Sorting="GridMultiColumnSortingEvent">

public static void GridMultiColumnSortingEvent(object sender, DataGridSortingEventArgs e)
        {
            var dgSender = (DataGrid)sender;
            var cView = CollectionViewSource.GetDefaultView(dgSender.ItemsSource);

            ListSortDirection direction = ListSortDirection.Ascending;
            if (ContainsSortColumn((DataGrid)sender, e.Column.SortMemberPath))
            {
                if (e.Column.SortDirection == null)
                {
                    direction = ListSortDirection.Ascending;
                    ChangeSortColumn((DataGrid)sender, e.Column, direction);
                }
                else if (DirectionForColumn(cView, e.Column) == ListSortDirection.Ascending)
                {
                    direction = ListSortDirection.Descending;
                    ChangeSortColumn((DataGrid)sender, e.Column, direction);
                }
                else if (DirectionForColumn(cView, e.Column) == ListSortDirection.Descending)
                {
                    e.Column.SortDirection = null;
                    cView.SortDescriptions.Remove(cView.SortDescriptions.Where(item => item.PropertyName.Equals(e.Column.SortMemberPath)).FirstOrDefault());
                    cView.Refresh();
                }
            }
            else
            {
                AddSortColumn((DataGrid)sender, e.Column.SortMemberPath, direction);
                cView.Refresh();
            }
            e.Handled = true;
        }

        private static ListSortDirection DirectionForColumn(ICollectionView cView, DataGridColumn column) =>
            cView.SortDescriptions.Where(item => item.PropertyName.Equals(column.SortMemberPath))
                 .FirstOrDefault()
                 .Direction;

        private static void AddSortColumn(DataGrid sender, string sortColumn, ListSortDirection direction)
        {
            var cView = CollectionViewSource.GetDefaultView(sender.ItemsSource);
            cView.SortDescriptions.Add(new SortDescription(sortColumn, direction));
            foreach (var col in sender.Columns.Where(x => x.SortMemberPath == sortColumn))
            {
                col.SortDirection = direction;
            }
        }

        private static void ChangeSortColumn(DataGrid sender, DataGridColumn column, ListSortDirection direction)
        {
            var cView = CollectionViewSource.GetDefaultView(sender.ItemsSource);
            string sortColumn = column.SortMemberPath;

            foreach (var sortDesc in cView.SortDescriptions.ToList())
            {
                if (sortDesc.PropertyName.Equals(sortColumn))
                {
                    cView.SortDescriptions.Remove(sortDesc);
                    break;
                }
            }

            AddSortColumn(sender, sortColumn, direction);
        }

        private static bool ContainsSortColumn(DataGrid sender, string sortColumn)
        {
            var cView = CollectionViewSource.GetDefaultView(sender.ItemsSource);
            foreach (var sortDesc in cView.SortDescriptions.ToList())
            {
                if (sortDesc.PropertyName.Equals(sortColumn))
                    return true;
            }
            return false;
        }
0

All Articles