Việc sắp xếp một đối tượng có thể quan sát và trả về cùng một đối tượng đã được sắp xếp có thể được thực hiện bằng phương pháp mở rộng. Đối với các bộ sưu tập lớn hơn, hãy để ý số lượng các thông báo thay đổi bộ sưu tập, ví dụ:
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++;
}
}
}
cách sử dụng: Lấy mẫu với một người quan sát (sử dụng một lớp Người để giữ cho nó đơn giản)
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();
};
Đầu ra từ phía trên:
loại bỏ Katy tuổi 51 ở chỉ số 0
thêm Katy tuổi 51 ở chỉ số 8
loại bỏ Mary tuổi 41 ở chỉ mục 3
đã thêm Mary tuổi 41 ở chỉ mục 7
đã xóa Jane tuổi 20 ở chỉ mục 3
đã thêm Jane tuổi 20 ở chỉ mục 5
đã loại bỏ Jim 39 tuổi ở chỉ số 3
đã thêm Jim tuổi 39 ở chỉ số 6
đã loại bỏ Jane tuổi 20 ở chỉ số 4
đã thêm Jane tuổi 20 ở chỉ số 5
Lớp Person triển khai cả ICompABLE và IEquatable, lớp sau này được sử dụng để giảm thiểu các thay đổi đối với bộ sưu tập để giảm số lượng thông báo thay đổi được đưa ra
- CHỈNH SỬA Sắp xếp cùng một bộ sưu tập mà không cần tạo một bản sao mới *
Để trả về một ObservableCollection, hãy gọi .ToObservableCollection trên * sortedOC * bằng cách sử dụng ví dụ: [triển khai này] [1].
**** Câu trả lời orig - điều này tạo ra một bộ sưu tập mới **** Bạn có thể sử dụng linq như phương thức doSort bên dưới minh họa. Đoạn mã nhanh: sản xuất
3: xey 6: fty 7: aaa
Ngoài ra, bạn có thể sử dụng một phương thức mở rộng trên chính bộ sưu tập
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;
}
}