Gözlemlenebilir bir nesnenin sıralanması ve sıralanan aynı nesnenin döndürülmesi, bir uzantı yöntemi kullanılarak yapılabilir. Daha büyük koleksiyonlar için, değişen koleksiyon bildirimlerinin sayısına dikkat edin.
Performansı artırmak ve kopyaları işlemek için kodumu güncelledim (orijinal veri örneğinde iyi çalışmasına rağmen orijinalin düşük performansını vurguladığı için nawfal'a teşekkürler). Gözlemlenebilir, soldan sıralanmış bir yarıya ve sağdan sıralanmamış bir yarıya bölünür; burada minimum öğe (sıralı listede bulunduğu gibi), sıralanmamış bölümden sıralı bölümün sonuna kaydırılır. En kötü durum O (n). Esasen bir seçim sıralaması (Çıktı için aşağıya bakın).
public static void Sort<T>(this ObservableCollection<T> collection)
where T : IComparable<T>, IEquatable<T>
{
List<T> sorted = collection.OrderBy(x => x).ToList();
int ptr = 0;
while (ptr < sorted.Count - 1)
{
if (!collection[ptr].Equals(sorted[ptr]))
{
int idx = search(collection, ptr+1, sorted[ptr]);
collection.Move(idx, ptr);
}
ptr++;
}
}
public static int search<T>(ObservableCollection<T> collection, int startIndex, T other)
{
for (int i = startIndex; i < collection.Count; i++)
{
if (other.Equals(collection[i]))
return i;
}
return -1; // decide how to handle error case
}
kullanım: Bir gözlemci ile örnekleme (basit tutmak için bir Kişi sınıfı kullandı)
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 = "Alice", Age = 39},
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 = 5},
new Person {Name = "Kim", Age = 19}
};
//what do observers see?
observable.CollectionChanged += (sender, e) =>
{
Console.WriteLine(
e.OldItems[0] + " move from " + e.OldStartingIndex + " to " + e.NewStartingIndex);
int i = 0;
foreach (var person in sender as ObservableCollection<Person>)
{
if (i == e.NewStartingIndex)
{
Console.Write("(" + (person as Person).Age + "),");
}
else
{
Console.Write((person as Person).Age + ",");
}
i++;
}
Console.WriteLine();
};
Koleksiyonun nasıl özetlendiğini gösteren sıralama ilerlemesinin ayrıntıları:
Sue aged 5 move from 8 to 0
(5),51,12,13,39,14,41,20,39,19,
Jack aged 12 move from 2 to 1
5,(12),51,13,39,14,41,20,39,19,
Bob aged 13 move from 3 to 2
5,12,(13),51,39,14,41,20,39,19,
John aged 14 move from 5 to 3
5,12,13,(14),51,39,41,20,39,19,
Kim aged 19 move from 9 to 4
5,12,13,14,(19),51,39,41,20,39,
Jane aged 20 move from 8 to 5
5,12,13,14,19,(20),51,39,41,39,
Alice aged 39 move from 7 to 6
5,12,13,14,19,20,(39),51,41,39,
Jim aged 39 move from 9 to 7
5,12,13,14,19,20,39,(39),51,41,
Mary aged 41 move from 9 to 8
5,12,13,14,19,20,39,39,(41),51,
Person sınıfı, hem IComparable hem de IEquatable'ı uygular; ikincisi, toplanan değişiklik bildirimlerinin sayısını azaltmak için koleksiyondaki değişiklikleri en aza indirmek için kullanılır.
- DÜZENLE Yeni bir kopya oluşturmadan aynı koleksiyonu sıralar *
Bir ObservableCollection döndürmek için, .ToObservableCollection öğesini * sıralıOC * kullanarak örneğin [bu uygulama] [1] kullanarak çağırın.
**** orig cevap - bu yeni bir koleksiyon oluşturur **** Aşağıdaki doSort yönteminde gösterildiği gibi linq'i kullanabilirsiniz. Hızlı bir kod parçacığı: üretir
3: xey 6: fty 7: aaa
Alternatif olarak, koleksiyonun kendisinde bir uzantı yöntemi kullanabilirsiniz.
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;
}
}