From 4336ec9e50e3aed9854653cc442df683f931b0ab Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 30 Apr 2021 15:15:00 +0100 Subject: [PATCH] Merge pull request #5847 from sdoroff/datagridcolumn-sortcomparer Added IComparer sorting to DataGridColumn --- .../Collections/DataGridSortDescription.cs | 37 +++++++++++++++++++ .../DataGridColumn.cs | 16 ++++++++ .../DataGridColumnHeader.cs | 6 +++ 3 files changed, 59 insertions(+) diff --git a/src/Avalonia.Controls.DataGrid/Collections/DataGridSortDescription.cs b/src/Avalonia.Controls.DataGrid/Collections/DataGridSortDescription.cs index 662ff91329..ca6020128c 100644 --- a/src/Avalonia.Controls.DataGrid/Collections/DataGridSortDescription.cs +++ b/src/Avalonia.Controls.DataGrid/Collections/DataGridSortDescription.cs @@ -265,6 +265,43 @@ namespace Avalonia.Collections { return new DataGridPathSortDescription(propertyPath, direction, comparer, null); } + + public static DataGridSortDescription FromComparer(IComparer comparer, ListSortDirection direction = ListSortDirection.Ascending) + { + return new DataGridComparerSortDesctiption(comparer, direction); + } + } + + public class DataGridComparerSortDesctiption : DataGridSortDescription + { + private readonly IComparer _innerComparer; + private readonly ListSortDirection _direction; + private readonly IComparer _comparer; + + public IComparer SourceComparer => _innerComparer; + public override IComparer Comparer => _comparer; + public override ListSortDirection Direction => _direction; + public DataGridComparerSortDesctiption(IComparer comparer, ListSortDirection direction) + { + _innerComparer = comparer; + _direction = direction; + _comparer = Comparer.Create((x, y) => Compare(x, y)); + } + + private int Compare(object x, object y) + { + int result = _innerComparer.Compare(x, y); + + if (Direction == ListSortDirection.Descending) + return -result; + else + return result; + } + public override DataGridSortDescription SwitchSortDirection() + { + var newDirection = _direction == ListSortDirection.Ascending ? ListSortDirection.Descending : ListSortDirection.Ascending; + return new DataGridComparerSortDesctiption(_innerComparer, newDirection); + } } public class DataGridSortDescriptionCollection : AvaloniaList diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs index 407d6ff058..9141fb2463 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs @@ -1009,6 +1009,14 @@ namespace Avalonia.Controls get; set; } + /// + /// Holds a Comparer to use for sorting, if not using the default. + /// + public System.Collections.IComparer CustomSortComparer + { + get; + set; + } /// /// We get the sort description from the data source. We don't worry whether we can modify sort -- perhaps the sort description @@ -1020,6 +1028,14 @@ namespace Avalonia.Controls && OwningGrid.DataConnection != null && OwningGrid.DataConnection.SortDescriptions != null) { + if(CustomSortComparer != null) + { + return + OwningGrid.DataConnection.SortDescriptions + .OfType() + .FirstOrDefault(s => s.SourceComparer == CustomSortComparer); + } + string propertyName = GetSortPropertyName(); return OwningGrid.DataConnection.SortDescriptions.FirstOrDefault(s => s.HasPropertyPath && s.PropertyPath == propertyName); diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs index 7f8d205949..6f957497cb 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs @@ -274,6 +274,12 @@ namespace Avalonia.Controls owningGrid.DataConnection.SortDescriptions.Add(newSort); } } + else if (OwningColumn.CustomSortComparer != null) + { + newSort = DataGridSortDescription.FromComparer(OwningColumn.CustomSortComparer); + + owningGrid.DataConnection.SortDescriptions.Add(newSort); + } else { string propertyName = OwningColumn.GetSortPropertyName();