OP Edit: many of them correctly pointed out that the original answer does not return the same collection (originally focused on sorting the vocabulary part of Q). See Editing below, where I refer to sorting an observable collection. The original stayed here, still getting voices
You can use linq, as the doSort method below shows. Quick code snippet: creates
3: Xey 6: FTY 7: aaa
Alternatively, you can use the extension method in the collection itself
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; } }
EDIT
To return an ObservableCollection, call .ToObservableCollection on sortedOC, using, for example, this implementation .
OP EDIT Sorting the observed and returning the same sorted object can be done using the extension method. For large collections, keep track of how many collection notifications have changed, e.g.
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++; } } }
usage: Sample with an observer (the Person class is used to make it simple)
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 } };
Output above:
deleted Katie at the age of 51 on index 0
added Katie at the age of 51 on index 8
deleted Mary at the age of 41 on index 3
added by Mary at the age of 41 on index 7
removed Jane at the age of 20 on index 3
added by Jane at age 20 on index 5
deleted Jim at the age of 39 on index 3
added by jim at age 39 on index 6
removed Jane at the age of 20 on index 4
added by Jane at age 20 on index 5
The Person class implements both IComparable and IEquatable, the latter is used to minimize changes to the collection to reduce the number of change notifications raised