Das Sortieren eines beobachtbaren Objekts und das Zurückgeben des gleichen sortierten Objekts kann mithilfe einer Erweiterungsmethode erfolgen. Achten Sie bei größeren Sammlungen auf die Anzahl der geänderten Sammlungsbenachrichtigungen, z
public static void Sort<T>(this ObservableCollection<T> observable) where T : IComparable<T>, IEquatable<T>
{
List<T> sorted = observable.OrderBy(x => x).ToList();
int ptr = 0;
while (ptr < sorted.Count)
{
if (!observable[ptr].Equals(sorted[ptr]))
{
T t = observable[ptr];
observable.RemoveAt(ptr);
observable.Insert(sorted.IndexOf(t), t);
}
else
{
ptr++;
}
}
}
Verwendung: Probe mit einem Beobachter (verwendet eine Personenklasse, um es einfach zu halten)
public class Person:IComparable<Person>,IEquatable<Person>
{
public string Name { get; set; }
public int Age { get; set; }
public int CompareTo(Person other)
{
if (this.Age == other.Age) return 0;
return this.Age.CompareTo(other.Age);
}
public override string ToString()
{
return Name + " aged " + Age;
}
public bool Equals(Person other)
{
if (this.Name.Equals(other.Name) && this.Age.Equals(other.Age)) return true;
return false;
}
}
static void Main(string[] args)
{
Console.WriteLine("adding items...");
var observable = new ObservableCollection<Person>()
{
new Person { Name = "Katy", Age = 51 },
new Person { Name = "Jack", Age = 12 },
new Person { Name = "Bob", Age = 13 },
new Person { Name = "John", Age = 14 },
new Person { Name = "Mary", Age = 41 },
new Person { Name = "Jane", Age = 20 },
new Person { Name = "Jim", Age = 39 },
new Person { Name = "Sue", Age = 15 },
new Person { Name = "Kim", Age = 19 }
};
//what do observers see?
observable.CollectionChanged += (o, e) => {
if (e.OldItems != null)
{
foreach (var item in e.OldItems)
{
Console.WriteLine("removed {0} at index {1}", item, e.OldStartingIndex);
}
}
if (e.NewItems != null)
{
foreach (var item in e.NewItems)
{
Console.WriteLine("added {0} at index {1}", item, e.NewStartingIndex);
}
}};
Console.WriteLine("\nsorting items...");
observable.Sort();
};
Ausgabe von oben:
entfernt Katy im Alter von 51 Jahren bei Index 0
hinzugefügt Katy im Alter von 51 Jahren bei Index 8
entfernt Mary im Alter von 41 Jahren bei Index 3
hinzugefügt Mary im Alter von 41 Jahren bei Index 7
entfernt Jane im Alter von 20 Jahren bei Index 3
hinzugefügt Jane im Alter von 20 Jahren bei Index 5
entfernt Jim im Alter von 39 Jahren bei Index 3
hinzugefügt Jim im Alter von 39 bei Index 6
Jane im Alter von 20 bei Index 4 entfernt
hinzugefügt Jane im Alter von 20 bei Index 5
Die Person-Klasse implementiert sowohl IComparable als auch IEquatable. Letzteres wird verwendet, um die Änderungen an der Sammlung zu minimieren und die Anzahl der ausgelösten Änderungsbenachrichtigungen zu verringern
- BEARBEITEN Sortiert dieselbe Sammlung, ohne eine neue Kopie zu erstellen *
Um eine ObservableCollection zurückzugeben, rufen Sie .ToObservableCollection auf * sortedOC * auf, indem Sie z. B. [diese Implementierung] [1] verwenden.
**** orig Antwort - dies erstellt eine neue Sammlung **** Sie können linq verwenden, wie die folgende doSort-Methode zeigt. Ein schneller Code-Ausschnitt: Erzeugt
3: xey 6: fty 7: aaa
Alternativ können Sie eine Erweiterungsmethode für die Sammlung selbst verwenden
var sortedOC = _collection.OrderBy(i => i.Key);
private void doSort()
{
ObservableCollection<Pair<ushort, string>> _collection =
new ObservableCollection<Pair<ushort, string>>();
_collection.Add(new Pair<ushort,string>(7,"aaa"));
_collection.Add(new Pair<ushort, string>(3, "xey"));
_collection.Add(new Pair<ushort, string>(6, "fty"));
var sortedOC = from item in _collection
orderby item.Key
select item;
foreach (var i in sortedOC)
{
Debug.WriteLine(i);
}
}
public class Pair<TKey, TValue>
{
private TKey _key;
public TKey Key
{
get { return _key; }
set { _key = value; }
}
private TValue _value;
public TValue Value
{
get { return _value; }
set { _value = value; }
}
public Pair(TKey key, TValue value)
{
_key = key;
_value = value;
}
public override string ToString()
{
return this.Key + ":" + this.Value;
}
}