Esta es la contestación más completa que encomtrarás compartir, pero obsérvala detenidamente y valora si se puede adaptar a tu trabajo.
Solución:
Introducción
Básicamente, si es necesario mostrar una colección ordenada, considere usar el CollectionViewSource
clase: asignar (“vincular”) su Source
propiedad a la colección de origen: una instancia de la ObservableCollection
clase.
la idea es que CollectionViewSource
La clase proporciona una instancia de la CollectionView
clase. Esta es una especie de “proyección” de la colección original (fuente), pero con clasificación aplicada, filtrado, etc.
Referencias:
- Cómo: ordenar y agrupar datos mediante una vista en XAML.
- CollectionViewSource de WPF.
Modelado en vivo
WPF 4.5 presenta la función “Live Shaping” para CollectionViewSource
.
Referencias:
- Nueva característica de WPF 4.5: modelado en vivo.
- Propiedad CollectionViewSource.IsLiveSorting.
- Reposicionamiento de datos a medida que cambian los valores de los datos (conformación en vivo).
Solución
Si todavía hay una necesidad de ordenar una instancia de la ObservableCollection
clase, así es como se puede hacer. los ObservableCollection
la clase en sí no tiene método de clasificación. Pero, 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
"Cat", "Dog", "Bear", "Lion", "Mouse",
"Horse", "Rat", "Elephant", "Kangaroo",
"Lizard", "Snake", "Frog", "Fish",
"Butterfly", "Human", "Cow", "Bumble Bee"
;
...
Animals = new ObservableCollection(Animals.OrderBy(i => i));
Detalles adicionales
Tenga en cuenta que OrderBy()
y OrderByDescending()
métodos (como otros métodos de extensión de LINQ) no modificar la colección fuente! ellos en cambio crear una nueva secuencia (es decir, una nueva instancia de la clase que implementa IEnumerable
interfaz). Por lo tanto, es necesario volver a crear la colección.
Sé que esta es una pregunta antigua, pero es el primer resultado de Google para “clasificar colección observable”, así que pensé que valía la pena dejar mi dos centavo.
El camino
La forma en que yo iría es construir un List<>
a partir de la ObservableCollection<>
ordenarlo (a través de su Sort()
método, más en msdn) y cuando el List<>
ha sido ordenado, reordene el ObservableCollection<>
con el Move()
método.
El código
public static void Sort(this ObservableCollection collection, Comparison comparison)
var sortableList = new List(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();
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 elements have been sorted
for (int i = 0; i < maxValue; i++)
Assert.AreEqual(i, observableCollection[i]);
notas
Esta es solo una prueba de concepto, que muestra cómo ordenar un ObservableCollection<>
sin romper los enlaces en los elementos. El algoritmo de clasificación tiene espacio para mejoras y validaciones (como la verificación de índice como se indica aquí).
Miré estos, lo estaba ordenando, y luego rompió la unión, como se indicó anteriormente. Se me ocurrió esta solución, aunque más simple que la mayoría de las suyas, parece hacer lo que quiero...
public static ObservableCollection OrderThoseGroups( ObservableCollection orderThoseGroups)
ObservableCollection temp;
temp = new ObservableCollection(orderThoseGroups.OrderBy(p => p));
orderThoseGroups.Clear();
foreach (string j in temp) orderThoseGroups.Add(j);
return orderThoseGroups;