c# sorting observablecollection order

Sort ObservableCollection<cadena> C#



sorting order (10)

Introducción

Básicamente, si es necesario mostrar una colección ordenada, considere usar la clase CollectionViewSource : asigne ("bind") su propiedad Source a la colección fuente, una instancia de la clase ObservableCollection<T> .

La idea es que la clase CollectionViewSource proporciona una instancia de la clase CollectionView . Esto es una especie de "proyección" de la colección original (fuente), pero con clasificación aplicada, filtrado, etc.

Referencias

Live Shaping

WPF 4.5 presenta la función "Live Shaping" para CollectionViewSource .

Referencias

Solución

Si todavía hay una necesidad de ordenar una instancia de la clase ObservableCollection<T> , aquí es cómo se puede hacer. La clase ObservableCollection<T> sí misma no tiene método de clasificación. Sin embargo, la colección podría volver a crearse para ordenar los elementos:

// 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));

Detalles adicionales

Tenga en cuenta que los OrderBy() y OrderByDescending() (como otros métodos de extensión LINQ) no modifican la colección de origen. En su lugar, crean una nueva secuencia (es decir, una nueva instancia de la clase que implementa la IEnumerable<T> ). Por lo tanto, es necesario volver a crear la colección.

Tengo debajo de ObservableCollection<string> . Necesito ordenar esto alfabéticamente.

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" };

Intenté _animals.OrderByDescending . pero no sé cómo usarlo correctamente.

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

Cómo puedo hacer esto ?


Creé un método de extensión para ObservableCollection

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); } }

Parece que funciona y no necesita implementar IComparable


El argumento de OrderByDescending es una función que devuelve una clave para ordenar con. En tu caso, la clave es la cadena en sí:

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

Si quiere ordenar por longitud, por ejemplo, escribirá:

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


Esta es una ObservableCollection<T> , que se ordena automáticamente cuando se produce un cambio, activa una clasificación solo cuando es necesario y solo activa una sola acción de cambio de la colección de movimientos.

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}, "); } } }

Salida:

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,


Miré esto, lo estaba ordenando, y luego rompió el enlace, como se indica arriba. Terminó con esta solución, aunque más simple que la mayoría de los suyos, parece hacer lo que yo quiero ...

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; }


Sé que es una vieja pregunta, pero es el primer resultado de google para "ordenar una colección observable", así que pensé que valía la pena dejar mi dos centavos.

La manera

La forma en que iría es crear una List<> partir de ObservableCollection<> , ordenarla (a través de su método Sort() , más en msdn ) y cuando se haya ordenado la List<> , vuelva a ordenar la ObservableCollection<> con la Método Move()

El código

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); } }

La prueba

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]); } }


Sorted My StoreData Collection de acuerdo con las calificaciones del modelo no es tan simple?

for (int index = 0; index < StoreData.Count-1; index++) { if (Convert.ToInt32(StoreData[index].Ratings) > Convert.ToInt32(StoreData[index + 1].Ratings)) { var temp = StoreData[index]; StoreData[index] = StoreData[index + 1]; StoreData[index + 1] = temp; } }


/// <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); } }

Esta solución se basa en la respuesta de Marco . Tuve algunos problemas con su solución y, por lo tanto, la mejoré al llamar a Move si el índice realmente cambió. Esto debería mejorar el rendimiento y también solucionar el problema vinculado.


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

Si los animales serían una lista del objeto Animal, podría usar una propiedad para ordenar la lista.

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


myObservableCollection.ToList().Sort((x, y) => x.Property.CompareTo(y.Property));