sortingObservableCollection <string> C#

我有下面的ObservableCollection<string> 。 我需要按字母顺序sorting。

 private ObservableCollection<string> _animals = new ObservableCollection<string> { "Cat", "Dog", "Bear", "Lion", "Mouse", "Horse", "Rat", "Elephant", "Kangaroo", "Lizard", "Snake", "Frog", "Fish", "Butterfly", "Human", "Cow", "Bumble Bee" }; 

我试过_animals.OrderByDescending 。 但我不知道如何正确使用它。

 _animals.OrderByDescending(a => a.<what_is_here_?>); 

我该怎么做?

介绍

基本上,如果需要显示已sorting的集合,请考虑使用CollectionViewSource类:将其Source属性分配(“绑定”)到源集合 – ObservableCollection<T>类的实例。

这个想法是CollectionViewSource类提供了CollectionViewSource类的一个实例 。 这是原始(源)集合的“投影”,但应用了分类,过滤等。

参考文献:

  • 如何使用XAML中的视图对数据进行sorting和分组
  • WPF的CollectionViewSource 。

实况塑造

WPF 4.5为CollectionViewSource引入了“实时整形”function。

参考文献:

  • WPF 4.5新function:实时成形 。
  • CollectionViewSource.IsLiveSorting属性 。
  • 随着数据值的变化重新定位数据(实时整形) 。

如果仍然需要对ObservableCollection<T>类的实例进行sorting,那么可以这样做。 ObservableCollection<T>类本身没有sorting方法。 但是,可以重新创build集合以使项目sorting:

 // Animals property setter must raise "property changed" event to notify binding clients. // See INotifyPropertyChanged interface for details. Animals = new ObservableCollection<string> { "Cat", "Dog", "Bear", "Lion", "Mouse", "Horse", "Rat", "Elephant", "Kangaroo", "Lizard", "Snake", "Frog", "Fish", "Butterfly", "Human", "Cow", "Bumble Bee" }; ... Animals = new ObservableCollection<string>(Animals.OrderBy(i => i)); 

额外细节

请注意, OrderBy()OrderByDescending()方法(与其他LINQ扩展方法一样) 不会修改源集合! 而是创build一个新的序列 (即实现IEnumerable<T>接口的类的新实例)。 因此,有必要重新创build集合。

我知道这是一个古老的问题,但它是第一个谷歌的结果“sortingobservablecollection”,所以认为值得离开我的两分。

方式

我会走的方式是从ObservableCollection<> List<>开始build立一个List<> ,对其进行Sort()通过它的Sort()方法, 在msdn上进行sorting),当List<>已经sorting时,用ObservableCollection<> Move()方法。

代码

 public static void Sort<T>(this ObservableCollection<T> collection, Comparison<T> comparison) { var sortableList = new List<T>(collection); sortableList.Sort(comparison); for (int i = 0; i < sortableList.Count; i++) { collection.Move(collection.IndexOf(sortableList[i]), i); } } 

考试

 public void TestObservableCollectionSortExtension() { var observableCollection = new ObservableCollection<int>(); var maxValue = 10; // Populate the list in reverse mode [maxValue, maxValue-1, ..., 1, 0] for (int i = maxValue; i >= 0; i--) { observableCollection.Add(i); } // Assert the collection is in reverse mode for (int i = maxValue; i >= 0; i--) { Assert.AreEqual(i, observableCollection[maxValue - i]); } // Sort the observable collection observableCollection.Sort((a, b) => { return a.CompareTo(b); }); // Assert element have been sorted for (int i = 0; i < maxValue; i++) { Assert.AreEqual(i, observableCollection[i]); } } 
 _animals.OrderByDescending(a => a.<what_is_here_?>); 

如果动物是动物对象列表,则可以使用属性来排列列表。

 public class Animal { public int ID {get; set;} public string Name {get; set;} ... } ObservableCollection<Animal> animals = ... animals = animals.OrderByDescending(a => a.Name); 

OrderByDescending的参数是一个返回键sorting的函数。 在你的情况下,关键是string本身:

 var result = _animals.OrderByDescending(a => a); 

如果你想按照时间sorting,你会写:

 var result = _animals.OrderByDescending(a => a.Length); 

我看着这些,我正在分类,然后打破了绑定,如上所述。 拿出这个解决scheme,虽然比你们大多数都简单,但它似乎是做我想要的,

 public static ObservableCollection<string> OrderThoseGroups( ObservableCollection<string> orderThoseGroups) { ObservableCollection<string> temp; temp = new ObservableCollection<string>(orderThoseGroups.OrderBy(p => p)); orderThoseGroups.Clear(); foreach (string j in temp) orderThoseGroups.Add(j); return orderThoseGroups; } 

我为ObservableCollection创build了一个扩展方法

 public static void MySort<TSource,TKey>(this ObservableCollection<TSource> observableCollection, Func<TSource, TKey> keySelector) { var a = observableCollection.OrderBy(keySelector).ToList(); observableCollection.Clear(); foreach(var b in a) { observableCollection.Add(b); } } 

这似乎工作,你不需要实现IComparable

 myObservableCollection.ToList().Sort((x, y) => x.Property.CompareTo(y.Property)); 
 /// <summary> /// Sorts the collection. /// </summary> /// <typeparam name="T">The type of the elements of the collection.</typeparam> /// <param name="collection">The collection to sort.</param> /// <param name="comparison">The comparison used for sorting.</param> public static void Sort<T>(this ObservableCollection<T> collection, Comparison<T> comparison = null) { var sortableList = new List<T>(collection); if (comparison == null) sortableList.Sort(); else sortableList.Sort(comparison); for (var i = 0; i < sortableList.Count; i++) { var oldIndex = collection.IndexOf(sortableList[i]); var newIndex = i; if (oldIndex != newIndex) collection.Move(oldIndex, newIndex); } } 

这个解决scheme是基于Marco的回答 。 我的解决scheme存在一些问题 ,因此只有在索引实际改变时才调用Move改进它。 这应该提高性能,并解决相关问题。

这是一个ObservableCollection<T> ,在更改时自动sorting,仅在必要时触发sorting,并且仅触发单个移动集合更改操作。

 using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; namespace ConsoleApp4 { using static Console; public class SortableObservableCollection<T> : ObservableCollection<T> { public Func<T, object> SortingSelector { get; set; } public bool Descending { get; set; } protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { base.OnCollectionChanged(e); if (e.Action != NotifyCollectionChangedAction.Reset && e.Action != NotifyCollectionChangedAction.Move && SortingSelector != null) { var query = this .Select((item, index) => (Item: item, Index: index)); query = Descending ? query.OrderBy(tuple => SortingSelector(tuple.Item)) : query.OrderByDescending(tuple => SortingSelector(tuple.Item)); var map = query.Select((tuple, index) => (OldIndex:tuple.Index, NewIndex:index)) .Where(o => o.OldIndex != o.NewIndex); using (var enumerator = map.GetEnumerator()) if (enumerator.MoveNext()) Move(enumerator.Current.OldIndex, enumerator.Current.NewIndex); } } } //USAGE class Program { static void Main(string[] args) { var xx = new SortableObservableCollection<int>() { SortingSelector = i => i }; xx.CollectionChanged += (sender, e) => WriteLine($"action: {e.Action}, oldIndex:{e.OldStartingIndex}," + " newIndex:{e.NewStartingIndex}, newValue: {xx[e.NewStartingIndex]}"); xx.Add(10); xx.Add(8); xx.Add(45); xx.Add(0); xx.Add(100); xx.Add(-800); xx.Add(4857); xx.Add(-1); foreach (var item in xx) Write($"{item}, "); } } } 

输出:

 action: Add, oldIndex:-1, newIndex:0, newValue: 10 action: Add, oldIndex:-1, newIndex:1, newValue: 8 action: Move, oldIndex:1, newIndex:0, newValue: 8 action: Add, oldIndex:-1, newIndex:2, newValue: 45 action: Add, oldIndex:-1, newIndex:3, newValue: 0 action: Move, oldIndex:3, newIndex:0, newValue: 0 action: Add, oldIndex:-1, newIndex:4, newValue: 100 action: Add, oldIndex:-1, newIndex:5, newValue: -800 action: Move, oldIndex:5, newIndex:0, newValue: -800 action: Add, oldIndex:-1, newIndex:6, newValue: 4857 action: Add, oldIndex:-1, newIndex:7, newValue: -1 action: Move, oldIndex:7, newIndex:1, newValue: -1 -800, -1, 0, 8, 10, 45, 100, 4857,