More sorting hacking
This commit is contained in:
parent
eb49dcfc54
commit
aa8e3ac09b
@ -118,7 +118,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
|
|
||||||
public void CollapseItem(SeriesEntrys2 sEntry)
|
public void CollapseItem(SeriesEntrys2 sEntry)
|
||||||
{
|
{
|
||||||
foreach (var episode in Items.BookEntries().Where(b => b.Parent == sEntry).ToList())
|
foreach (var episode in Items.BookEntries().Where(b => b.Parent == sEntry).OrderByDescending(lbe => lbe.SeriesIndex).ToList())
|
||||||
{
|
{
|
||||||
Remove(episode);
|
Remove(episode);
|
||||||
}
|
}
|
||||||
@ -128,11 +128,13 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
|
|
||||||
public void ExpandItem(SeriesEntrys2 sEntry)
|
public void ExpandItem(SeriesEntrys2 sEntry)
|
||||||
{
|
{
|
||||||
foreach (var episode in FilterRemoved.BookEntries().Where(b => b.Parent == sEntry).ToList())
|
var sindex = Items.IndexOf(sEntry);
|
||||||
|
|
||||||
|
foreach (var episode in FilterRemoved.BookEntries().Where(b => b.Parent == sEntry).OrderByDescending(lbe => lbe.SeriesIndex).ToList())
|
||||||
{
|
{
|
||||||
if (SearchResults is null || SearchResults.Docs.Any(d => d.ProductId == episode.AudibleProductId))
|
if (SearchResults is null || SearchResults.Docs.Any(d => d.ProductId == episode.AudibleProductId))
|
||||||
{
|
{
|
||||||
Add(episode);
|
InsertItem(++sindex, episode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sEntry.Liberate.Expanded = true;
|
sEntry.Liberate.Expanded = true;
|
||||||
|
|||||||
@ -9,13 +9,12 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace LibationWinForms.AvaloniaUI.ViewModels
|
namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||||
{
|
{
|
||||||
//TODO keep episodes beneath their parents when other entries compare equal (because as it stands, children always compare > parents.
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This compare class ensures that all top-level grid entries (standalone books or series parents)
|
/// This compare class ensures that all top-level grid entries (standalone books or series parents)
|
||||||
/// are sorted by PropertyName while all episodes remain immediately beneath their parents and remain
|
/// are sorted by PropertyName while all episodes remain immediately beneath their parents and remain
|
||||||
/// sorted by series index, ascending.
|
/// sorted by series index, ascending.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class RowComparer : IComparer
|
internal class RowComparer : IComparer, IComparer<GridEntry2>
|
||||||
{
|
{
|
||||||
private static readonly System.Reflection.PropertyInfo HeaderCellPi = typeof(DataGridColumn).GetProperty("HeaderCell", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
private static readonly System.Reflection.PropertyInfo HeaderCellPi = typeof(DataGridColumn).GetProperty("HeaderCell", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
private static readonly System.Reflection.PropertyInfo CurrentSortingStatePi = typeof(DataGridColumnHeader).GetProperty("CurrentSortingState", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
private static readonly System.Reflection.PropertyInfo CurrentSortingStatePi = typeof(DataGridColumnHeader).GetProperty("CurrentSortingState", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
@ -29,6 +28,11 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
Column = column;
|
Column = column;
|
||||||
PropertyName = Column.SortMemberPath;
|
PropertyName = Column.SortMemberPath;
|
||||||
}
|
}
|
||||||
|
public RowComparer(ListSortDirection direction, string propertyName)
|
||||||
|
{
|
||||||
|
SortDirection = direction;
|
||||||
|
PropertyName = propertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public int Compare(object x, object y)
|
public int Compare(object x, object y)
|
||||||
@ -50,11 +54,26 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
if (geB is LibraryBookEntry2 lbB && lbB.Parent is SeriesEntrys2 seB)
|
if (geB is LibraryBookEntry2 lbB && lbB.Parent is SeriesEntrys2 seB)
|
||||||
parentB = seB;
|
parentB = seB;
|
||||||
|
|
||||||
|
if (geA is SeriesEntrys2 && geB is SeriesEntrys2)
|
||||||
|
{
|
||||||
|
//Both are parents. Make sure they never compare equal.
|
||||||
|
var comparison = InternalCompare(geA, geB);
|
||||||
|
if (comparison == 0)
|
||||||
|
{
|
||||||
|
var propBackup = PropertyName;
|
||||||
|
PropertyName = nameof(GridEntry2.Series);
|
||||||
|
comparison = InternalCompare(geA, geB);
|
||||||
|
PropertyName = propBackup;
|
||||||
|
return comparison;
|
||||||
|
}
|
||||||
|
return comparison;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//both a and b are standalone
|
//both a and b are standalone
|
||||||
if (parentA is null && parentB is null)
|
if (parentA is null && parentB is null)
|
||||||
return Compare(geA, geB);
|
return InternalCompare(geA, geB);
|
||||||
|
|
||||||
//a is a standalone, b is a child
|
//a is a standalone, b is a child
|
||||||
if (parentA is null && parentB is not null)
|
if (parentA is null && parentB is not null)
|
||||||
@ -62,8 +81,22 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
// b is a child of a, parent is always first
|
// b is a child of a, parent is always first
|
||||||
if (parentB == geA)
|
if (parentB == geA)
|
||||||
return SortDirection is ListSortDirection.Ascending ? -1 : 1;
|
return SortDirection is ListSortDirection.Ascending ? -1 : 1;
|
||||||
|
else if (geA is SeriesEntrys2)
|
||||||
|
{
|
||||||
|
//Both are parents. Make sure they never compare equal.
|
||||||
|
var comparison = InternalCompare(geA, parentB);
|
||||||
|
if (comparison == 0)
|
||||||
|
{
|
||||||
|
var propBackup = PropertyName;
|
||||||
|
PropertyName = nameof(GridEntry2.Series);
|
||||||
|
comparison = InternalCompare(geA, parentB);
|
||||||
|
PropertyName = propBackup;
|
||||||
|
return comparison;
|
||||||
|
}
|
||||||
|
return comparison;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return Compare(geA, parentB);
|
return InternalCompare(geA, parentB);
|
||||||
}
|
}
|
||||||
|
|
||||||
//a is a child, b is a standalone
|
//a is a child, b is a standalone
|
||||||
@ -72,28 +105,61 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
// a is a child of b, parent is always first
|
// a is a child of b, parent is always first
|
||||||
if (parentA == geB)
|
if (parentA == geB)
|
||||||
return SortDirection is ListSortDirection.Ascending ? 1 : -1;
|
return SortDirection is ListSortDirection.Ascending ? 1 : -1;
|
||||||
|
else if (geB is SeriesEntrys2)
|
||||||
|
{
|
||||||
|
//Both are parents. Make sure they never compare equal.
|
||||||
|
var comparison = InternalCompare(parentA, geB);
|
||||||
|
if (comparison == 0)
|
||||||
|
{
|
||||||
|
var propBackup = PropertyName;
|
||||||
|
PropertyName = nameof(GridEntry2.Series);
|
||||||
|
comparison = InternalCompare(parentA, geB);
|
||||||
|
PropertyName = propBackup;
|
||||||
|
return comparison;
|
||||||
|
}
|
||||||
|
return comparison;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return Compare(parentA, geB);
|
return InternalCompare(parentA, geB);
|
||||||
}
|
}
|
||||||
|
|
||||||
//both are children of the same series, always present in order of series index, ascending
|
//both are children of the same series, always present in order of series index, ascending
|
||||||
if (parentA == parentB)
|
if (parentA == parentB)
|
||||||
return geA.SeriesIndex.CompareTo(geB.SeriesIndex) * (SortDirection is ListSortDirection.Ascending ? 1 : -1);
|
return geA.SeriesIndex.CompareTo(geB.SeriesIndex) * (SortDirection is ListSortDirection.Ascending ? 1 : -1);
|
||||||
|
|
||||||
//a and b are children of different series.
|
//a and b are children of different series. Make sure their parents never compare equal.
|
||||||
return Compare(parentA, parentB);
|
var comparison2 = InternalCompare(parentA, parentB);
|
||||||
|
if (comparison2 == 0)
|
||||||
|
{
|
||||||
|
var propBackup = PropertyName;
|
||||||
|
PropertyName = nameof(GridEntry2.Series);
|
||||||
|
comparison2 = InternalCompare(parentA, parentB);
|
||||||
|
PropertyName = propBackup;
|
||||||
|
return comparison2;
|
||||||
|
}
|
||||||
|
return comparison2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Avalonia doesn't expose the column's CurrentSortingState, so we must get it through reflection
|
//Avalonia doesn't expose the column's CurrentSortingState, so we must get it through reflection
|
||||||
private ListSortDirection? GetSortOrder()
|
private ListSortDirection? GetSortOrder()
|
||||||
=> CurrentSortingStatePi.GetValue(HeaderCellPi.GetValue(Column)) as ListSortDirection?;
|
=> CurrentSortingStatePi.GetValue(HeaderCellPi.GetValue(Column)) as ListSortDirection?;
|
||||||
|
|
||||||
private int Compare(GridEntry2 x, GridEntry2 y)
|
private int InternalCompare(GridEntry2 x, GridEntry2 y)
|
||||||
{
|
{
|
||||||
var val1 = x.GetMemberValue(PropertyName);
|
var val1 = x.GetMemberValue(PropertyName);
|
||||||
var val2 = y.GetMemberValue(PropertyName);
|
var val2 = y.GetMemberValue(PropertyName);
|
||||||
|
|
||||||
return x.GetMemberComparer(val1.GetType()).Compare(val1, val2);
|
return x.GetMemberComparer(val1.GetType()).Compare(val1, val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int CompareTo(GridEntry2 other)
|
||||||
|
{
|
||||||
|
return Compare(this, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Compare(GridEntry2 x, GridEntry2 y)
|
||||||
|
{
|
||||||
|
return Compare((object)x, (object)y) * (SortDirection is ListSortDirection.Ascending ? 1 : -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -171,7 +171,7 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
{
|
{
|
||||||
if (CurrentSortColumn is null)
|
if (CurrentSortColumn is null)
|
||||||
{
|
{
|
||||||
bindingList.InternalList.Sort((i1, i2) => i2.DateAdded.CompareTo(i1.DateAdded));
|
bindingList.InternalList.Sort(new RowComparer(ListSortDirection.Descending, nameof(GridEntry2.DateAdded)));
|
||||||
bindingList.ResetCollection();
|
bindingList.ResetCollection();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user