From 9bca84dca459712928f734afaad5eb1ac24e8004 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 28 Jul 2025 09:29:17 -0600 Subject: [PATCH] Sort columns with null values always at the bottom --- Source/LibationUiBase/GridView/GridEntry.cs | 19 ++++++++++++++- .../GridView/RowComparerBase.cs | 23 +++++++++++++------ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Source/LibationUiBase/GridView/GridEntry.cs b/Source/LibationUiBase/GridView/GridEntry.cs index 6f4549a2..665859f1 100644 --- a/Source/LibationUiBase/GridView/GridEntry.cs +++ b/Source/LibationUiBase/GridView/GridEntry.cs @@ -210,6 +210,24 @@ namespace LibationUiBase.GridView nameof(IsSpatial) => IsSpatial, _ => null }; + + public bool MemberValueIsDefault(string memberName) => memberName switch + { + nameof(Series) => Book.SeriesLink?.Any() is not true, + nameof(SeriesOrder) => string.IsNullOrWhiteSpace(SeriesOrder.OrderString), + nameof(MyRating) => RatingIsDefault(Book.UserDefinedItem.Rating), + nameof(ProductRating) => RatingIsDefault(Book.Rating), + nameof(Authors) => string.IsNullOrWhiteSpace(Authors), + nameof(Narrators) => string.IsNullOrWhiteSpace(Narrators), + nameof(Description) => string.IsNullOrWhiteSpace(Description), + nameof(Category) => string.IsNullOrWhiteSpace(Category), + nameof(Misc) => string.IsNullOrWhiteSpace(Misc), + nameof(BookTags) => string.IsNullOrWhiteSpace(BookTags), + _ => false + }; + + private static bool RatingIsDefault(Rating rating) + => rating is null || (rating.OverallRating == 0 && rating.PerformanceRating == 0 && rating.StoryRating == 0); public IComparer GetMemberComparer(Type memberType) => memberTypeComparers.TryGetValue(memberType, out IComparer value) ? value : memberTypeComparers[memberType.BaseType]; @@ -341,7 +359,6 @@ namespace LibationUiBase.GridView return (await Task.WhenAll(tasks)).SelectMany(a => a).ToList(); } - ~GridEntry() { PictureStorage.PictureCached -= PictureStorage_PictureCached; diff --git a/Source/LibationUiBase/GridView/RowComparerBase.cs b/Source/LibationUiBase/GridView/RowComparerBase.cs index dab24a38..91298207 100644 --- a/Source/LibationUiBase/GridView/RowComparerBase.cs +++ b/Source/LibationUiBase/GridView/RowComparerBase.cs @@ -21,15 +21,24 @@ namespace LibationUiBase.GridView private int InternalCompare(GridEntry x, GridEntry y) { - var val1 = x.GetMemberValue(PropertyName); - var val2 = y.GetMemberValue(PropertyName); + //Default values (e.g. empty strings) always sort to the end of the list. + var val1IsDefault = x.MemberValueIsDefault(PropertyName); + var val2IsDefault = y.MemberValueIsDefault(PropertyName); - var compare = x.GetMemberComparer(val1.GetType()).Compare(val1, val2); + if (val1IsDefault && val2IsDefault) return 0; + else if (val1IsDefault && !val2IsDefault) return GetSortOrder() is ListSortDirection.Ascending ? 1 : -1; + else if (!val1IsDefault && val2IsDefault) return GetSortOrder() is ListSortDirection.Ascending ? -1 : 1; + else + { + var val1 = x.GetMemberValue(PropertyName); + var val2 = y.GetMemberValue(PropertyName); + var compare = x.GetMemberComparer(val1.GetType()).Compare(val1, val2); - return compare == 0 && x.Liberate.IsSeries && y.Liberate.IsSeries - //Both a and b are series parents and compare as equal, so break the tie. - ? x.AudibleProductId.CompareTo(y.AudibleProductId) - : compare; + return compare == 0 && x.Liberate.IsSeries && y.Liberate.IsSeries + //Both a and b are series parents and compare as equal, so break the tie. + ? x.AudibleProductId.CompareTo(y.AudibleProductId) + : compare; + } } public int Compare(GridEntry? geA, GridEntry? geB)