Skip to content

Commit ff357ad

Browse files
committed
Add IComparer overload to SortDescription
1 parent 13fdad7 commit ff357ad

File tree

3 files changed

+172
-7
lines changed

3 files changed

+172
-7
lines changed

Microsoft.Toolkit.Uwp.UI/AdvancedCollectionView/AdvancedCollectionView.cs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -377,24 +377,26 @@ int IComparer<object>.Compare(object x, object y)
377377

378378
foreach (var sd in _sortDescriptions)
379379
{
380-
IComparable cx, cy;
380+
object cx, cy;
381381

382382
if (string.IsNullOrEmpty(sd.PropertyName))
383383
{
384-
cx = x as IComparable;
385-
cy = y as IComparable;
384+
cx = x;
385+
cy = y;
386386
}
387387
else
388388
{
389389
var pi = _sortProperties[sd.PropertyName];
390-
cx = pi.GetValue(x) as IComparable;
391-
cy = pi.GetValue(y) as IComparable;
390+
391+
cx = pi.GetValue(x);
392+
cy = pi.GetValue(y);
392393
}
393394

394395
try
395396
{
396-
// ReSharper disable once PossibleUnintendedReferenceComparison
397-
var cmp = cx == cy ? 0 : cx == null ? -1 : cy == null ? +1 : cx.CompareTo(cy);
397+
var comparer = sd.Comparer ?? ComparerAdapter.Instance;
398+
var cmp = comparer.Compare(cx, cy);
399+
398400
if (cmp != 0)
399401
{
400402
return sd.Direction == SortDirection.Ascending ? +cmp : -cmp;
@@ -602,5 +604,23 @@ private bool MoveCurrentToIndex(int i)
602604
OnCurrentChanged(null);
603605
return true;
604606
}
607+
608+
private class ComparerAdapter : IComparer
609+
{
610+
public static readonly IComparer Instance = new ComparerAdapter();
611+
612+
private ComparerAdapter()
613+
{
614+
}
615+
616+
public int Compare(object x, object y)
617+
{
618+
var cx = x as IComparable;
619+
var cy = y as IComparable;
620+
621+
// ReSharper disable once PossibleUnintendedReferenceComparison
622+
return cx == cy ? 0 : cx == null ? -1 : cy == null ? +1 : cx.CompareTo(cy);
623+
}
624+
}
605625
}
606626
}

Microsoft.Toolkit.Uwp.UI/AdvancedCollectionView/SortDescription.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
1111
// ******************************************************************
1212

13+
using System.Collections;
14+
1315
namespace Microsoft.Toolkit.Uwp.UI
1416
{
1517
/// <summary>
@@ -27,6 +29,11 @@ public class SortDescription
2729
/// </summary>
2830
public SortDirection Direction { get; }
2931

32+
/// <summary>
33+
/// Gets the comparer
34+
/// </summary>
35+
public IComparer Comparer { get; }
36+
3037
/// <summary>
3138
/// Initializes a new instance of the <see cref="SortDescription"/> class that describes
3239
/// a sort on the object itself
@@ -37,6 +44,18 @@ public SortDescription(SortDirection direction)
3744
Direction = direction;
3845
}
3946

47+
/// <summary>
48+
/// Initializes a new instance of the <see cref="SortDescription"/> class that describes
49+
/// a sort on the object itself
50+
/// </summary>
51+
/// <param name="direction">directio of sort</param>
52+
/// <param name="comparer">comparer to use</param>
53+
public SortDescription(SortDirection direction, IComparer comparer)
54+
{
55+
Direction = direction;
56+
Comparer = comparer;
57+
}
58+
4059
/// <summary>
4160
/// Initializes a new instance of the <see cref="SortDescription"/> class.
4261
/// </summary>
@@ -47,5 +66,18 @@ public SortDescription(string propertyName, SortDirection direction)
4766
PropertyName = propertyName;
4867
Direction = direction;
4968
}
69+
70+
/// <summary>
71+
/// Initializes a new instance of the <see cref="SortDescription"/> class.
72+
/// </summary>
73+
/// <param name="propertyName">name of property to sort on</param>
74+
/// <param name="direction">direction of sort</param>
75+
/// <param name="comparer">comparer to use</param>
76+
public SortDescription(string propertyName, SortDirection direction, IComparer comparer)
77+
{
78+
PropertyName = propertyName;
79+
Direction = direction;
80+
Comparer = comparer;
81+
}
5082
}
5183
}

UnitTests/UI/Test_AdvancedCollectionView.cs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
1111
// ******************************************************************
1212

13+
using System;
14+
using System.Collections;
1315
using System.Collections.Generic;
1416
using System.Collections.ObjectModel;
1517
using System.Linq;
1618
using Microsoft.Toolkit.Uwp.UI;
1719
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
1820
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework.AppContainer;
21+
1922
using Assert = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.Assert;
2023

2124
namespace UnitTests.UI
@@ -229,5 +232,115 @@ public void Test_AdvancedCollectionView_Sorting_OnSelf()
229232

230233
Assert.AreEqual(((Person)a.First()).Age, 42);
231234
}
235+
236+
[TestCategory("AdvancedCollectionView")]
237+
[UITestMethod]
238+
public void Test_AdvancedCollectionView_Sorting_OnSelf_CustomComparable()
239+
{
240+
var l = new ObservableCollection<Person>
241+
{
242+
new Person()
243+
{
244+
Name = "lorem",
245+
Age = 4
246+
},
247+
new Person()
248+
{
249+
Name = "imsum",
250+
Age = 8
251+
},
252+
new Person()
253+
{
254+
Name = "dolor",
255+
Age = 15
256+
},
257+
new Person()
258+
{
259+
Name = "sit",
260+
Age = 16
261+
},
262+
new Person()
263+
{
264+
Name = "amet",
265+
Age = 23
266+
},
267+
new Person()
268+
{
269+
Name = "consectetur",
270+
Age = 42
271+
},
272+
};
273+
274+
var a = new AdvancedCollectionView(l)
275+
{
276+
SortDescriptions =
277+
{
278+
new SortDescription(SortDirection.Ascending, new DelegateComparable((x, y) => -((Person)x).Age.CompareTo(((Person)y).Age)))
279+
}
280+
};
281+
282+
Assert.AreEqual(((Person)a.First()).Age, 42);
283+
}
284+
285+
[TestCategory("AdvancedCollectionView")]
286+
[UITestMethod]
287+
public void Test_AdvancedCollectionView_Sorting_CustomComparable()
288+
{
289+
var l = new ObservableCollection<Person>
290+
{
291+
new Person()
292+
{
293+
Name = "lorem",
294+
Age = 4
295+
},
296+
new Person()
297+
{
298+
Name = "imsum",
299+
Age = 8
300+
},
301+
new Person()
302+
{
303+
Name = "dolor",
304+
Age = 15
305+
},
306+
new Person()
307+
{
308+
Name = "sit",
309+
Age = 16
310+
},
311+
new Person()
312+
{
313+
Name = "amet",
314+
Age = 23
315+
},
316+
new Person()
317+
{
318+
Name = "consectetur",
319+
Age = 42
320+
},
321+
};
322+
323+
var a = new AdvancedCollectionView(l)
324+
{
325+
SortDescriptions =
326+
{
327+
new SortDescription(nameof(Person.Age), SortDirection.Ascending, new DelegateComparable((x, y) => -((int)x).CompareTo((int)y)))
328+
}
329+
};
330+
331+
Assert.AreEqual(((Person)a.First()).Age, 42);
332+
}
333+
334+
private class DelegateComparable : IComparer
335+
{
336+
private Func<object, object, int> _func;
337+
338+
public DelegateComparable(Func<object, object, int> func)
339+
{
340+
_func = func;
341+
}
342+
343+
public int Compare(object x, object y) => _func(x, y);
344+
}
232345
}
233346
}

0 commit comments

Comments
 (0)