C# 资源插入(j,o1); } } } }
调用OrderBy的方法与调用OrderBy的方法相同,只是它将对ObservableCollection的现有实例进行排序,而不是返回新集合:C# 资源插入(j,o1); } } } },c#,.net,wpf,sorting,observablecollection,C#,.net,Wpf,Sorting,Observablecollection,调用OrderBy的方法与调用OrderBy的方法相同,只是它将对ObservableCollection的现有实例进行排序,而不是返回新集合: ObservableCollection<Person> people = new ObservableCollection<Person>(); ... people.Sort(p => p.FirstName); observedcollection people=newobservedcollection();
ObservableCollection<Person> people = new ObservableCollection<Person>();
...
people.Sort(p => p.FirstName);
observedcollection people=newobservedcollection();
...
people.Sort(p=>p.FirstName);
为了稍微改进xr280xr answer上的扩展方法,我添加了一个可选的bool参数来确定排序是否在下降。我还将Carlos P提出的建议包括在对该答案的评论中。请看下面
public static void Sort<TSource, TKey>(this ObservableCollection<TSource> source, Func<TSource, TKey> keySelector, bool desc = false)
{
if (source == null) return;
Comparer<TKey> comparer = Comparer<TKey>.Default;
for (int i = source.Count - 1; i >= 0; i--)
{
for (int j = 1; j <= i; j++)
{
TSource o1 = source[j - 1];
TSource o2 = source[j];
int comparison = comparer.Compare(keySelector(o1), keySelector(o2));
if (desc && comparison < 0)
source.Move(j, j - 1);
else if (!desc && comparison > 0)
source.Move(j - 1, j);
}
}
}
public static void Sort(此ObservableCollection源,Func keySelector,bool desc=false)
{
if(source==null)返回;
Comparer=Comparer.Default;
对于(int i=source.Count-1;i>=0;i--)
{
对于(int j=1;j 0)
来源.移动(j-1,j);
}
}
}
变体是使用算法对集合进行排序的地方。使用该方法将图元移动到位。每次移动都会触发带有NotifyCollectionChangedAction.move
(以及属性名项[]
)的事件
此算法具有一些很好的特性:
- 该算法可以实现为一个稳定的排序
- 在集合中移动的项目数(例如,
events fired)几乎总是少于其他类似算法,如插入排序和冒泡排序CollectionChanged
IComparable
。其他选项是使用IComparer
或Func
公共静态类ObservableCollectionExtensions{
公共静态空排序(此ObservableCollection集合),其中T:IComparable{
if(集合==null)
抛出新的ArgumentNullException(“集合”);
对于(var startIndex=0;startIndex
对集合排序只需调用扩展方法:
var collection = new ObservableCollection<String>(...);
collection.Sort();
var集合=新的可观察集合(…);
collection.Sort();
var collection=newobservetecollection();
增加(7);
增加(4);
增加(12);
增加第(1)款;
增加(20);
//上升的
collection=newobserveCollection(collection.OrderBy(a=>a));
//下降的
collection=newobserveCollection(collection.OrderByDescending(a=>a));
见鬼,我也会快速拼凑出一个答案……它看起来有点像这里的其他实现,但我会添加它:
(几乎没有测试,希望我没有让自己难堪)
让我们先陈述一些目标(我的假设):
1) 必须对可观察收集进行排序,以维护通知等
2) 不能非常低效(即接近标准“良好”分拣效率)
公共静态类Ext
{
公共静态无效排序(此ObservableCollection src)
其中T:i可比较
{
//一些初步的安全检查
如果(src==null)抛出新的ArgumentNullException(“src”);
如果(!src.Any())返回;
//N对于选择,
//+~N log N,假设OrderBy上的“智能”排序实现
//总计:N对数N+N(东部标准)
var indexedPairs=src
.Select((项目,i)=>Tuple.Create(项目))
.OrderBy(tup=>tup.Item2);
//N表示另一个选择
var postIndexedPairs=indexedPairs
.Select((item,i)=>Tuple.Create(i,item.Item1,item.Item2));
//N表示每个元素上的循环
var pairEnum=postIndexedPairs.GetEnumerator();
pairEnum.MoveNext();
对于(int idx=0;idx
这个简单的扩展非常适合我。我只需要确保MyObject
是I可比较的
。当对MyObjects
的可观察集合调用sort方法时,调用MyObject
上的CompareTo
方法,该方法调用我的逻辑排序方法。虽然它没有所有的铃铛和口哨的其余答案张贴在这里,这正是我所需要的
static class Extensions
{
public static void Sort<T>(this ObservableCollection<T> collection) where T : IComparable
{
List<T> sorted = collection.OrderBy(x => x).ToList();
for (int i = 0; i < sorted.Count(); i++)
collection.Move(collection.IndexOf(sorted[i]), i);
}
}
public class MyObject: IComparable
{
public int CompareTo(object o)
{
MyObject a = this;
MyObject b = (MyObject)o;
return Utils.LogicalStringCompare(a.Title, b.Title);
}
public string Title;
}
.
.
.
myCollection = new ObservableCollection<MyObject>();
//add stuff to collection
myCollection.Sort();
静态类扩展
{
公共静态空排序(此ObservableCollection集合),其中T:IComparable
{
List sorted=collection.OrderBy(x=>x.ToList();
for(int i=0;iSue 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,
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;
}
}
my_collection.OrderBy(p => p.Key);
my_collection.ToList().Sort((left, right) => left == right ? 0 : (left > right ? -1 : 1));
public static void Sort<TSource, TKey>(this Collection<TSource> source, Func<TSource, TKey> keySelector)
{
List<TSource> sortedList = source.OrderBy(keySelector).ToList();
source.Clear();
foreach (var sortedItem in sortedList)
source.Add(sortedItem);
}
_collection.Sort(i => i.Key);
public static void Sort<TSource, TKey>(this ObservableCollection<TSource> source, Func<TSource, TKey> keySelector)
{
if (source == null) return;
Comparer<TKey> comparer = Comparer<TKey>.Default;
for (int i = source.Count - 1; i >= 0; i--)
{
for (int j = 1; j <= i; j++)
{
TSource o1 = source[j - 1];
TSource o2 = source[j];
if (comparer.Compare(keySelector(o1), keySelector(o2)) > 0)
{
source.Remove(o1);
source.Insert(j, o1);
}
}
}
}
ObservableCollection<Person> people = new ObservableCollection<Person>();
...
people.Sort(p => p.FirstName);
public static void Sort<TSource, TKey>(this ObservableCollection<TSource> source, Func<TSource, TKey> keySelector, bool desc = false)
{
if (source == null) return;
Comparer<TKey> comparer = Comparer<TKey>.Default;
for (int i = source.Count - 1; i >= 0; i--)
{
for (int j = 1; j <= i; j++)
{
TSource o1 = source[j - 1];
TSource o2 = source[j];
int comparison = comparer.Compare(keySelector(o1), keySelector(o2));
if (desc && comparison < 0)
source.Move(j, j - 1);
else if (!desc && comparison > 0)
source.Move(j - 1, j);
}
}
}
public static class ObservableCollectionExtensions {
public static void Sort<T>(this ObservableCollection<T> collection) where T : IComparable<T> {
if (collection == null)
throw new ArgumentNullException("collection");
for (var startIndex = 0; startIndex < collection.Count - 1; startIndex += 1) {
var indexOfSmallestItem = startIndex;
for (var i = startIndex + 1; i < collection.Count; i += 1)
if (collection[i].CompareTo(collection[indexOfSmallestItem]) < 0)
indexOfSmallestItem = i;
if (indexOfSmallestItem != startIndex)
collection.Move(indexOfSmallestItem, startIndex);
}
}
}
var collection = new ObservableCollection<String>(...);
collection.Sort();
var collection = new ObservableCollection<int>();
collection.Add(7);
collection.Add(4);
collection.Add(12);
collection.Add(1);
collection.Add(20);
// ascending
collection = new ObservableCollection<int>(collection.OrderBy(a => a));
// descending
collection = new ObservableCollection<int>(collection.OrderByDescending(a => a));
public static class Ext
{
public static void Sort<T>(this ObservableCollection<T> src)
where T : IComparable<T>
{
// Some preliminary safety checks
if(src == null) throw new ArgumentNullException("src");
if(!src.Any()) return;
// N for the select,
// + ~ N log N, assuming "smart" sort implementation on the OrderBy
// Total: N log N + N (est)
var indexedPairs = src
.Select((item,i) => Tuple.Create(i, item))
.OrderBy(tup => tup.Item2);
// N for another select
var postIndexedPairs = indexedPairs
.Select((item,i) => Tuple.Create(i, item.Item1, item.Item2));
// N for a loop over every element
var pairEnum = postIndexedPairs.GetEnumerator();
pairEnum.MoveNext();
for(int idx = 0; idx < src.Count; idx++, pairEnum.MoveNext())
{
src.RemoveAt(pairEnum.Current.Item1);
src.Insert(idx, pairEnum.Current.Item3);
}
// (very roughly) Estimated Complexity:
// N log N + N + N + N
// == N log N + 3N
}
}
static class Extensions
{
public static void Sort<T>(this ObservableCollection<T> collection) where T : IComparable
{
List<T> sorted = collection.OrderBy(x => x).ToList();
for (int i = 0; i < sorted.Count(); i++)
collection.Move(collection.IndexOf(sorted[i]), i);
}
}
public class MyObject: IComparable
{
public int CompareTo(object o)
{
MyObject a = this;
MyObject b = (MyObject)o;
return Utils.LogicalStringCompare(a.Title, b.Title);
}
public string Title;
}
.
.
.
myCollection = new ObservableCollection<MyObject>();
//add stuff to collection
myCollection.Sort();
public class ScoutItems : ObservableCollection<ScoutItem>
{
public void Sort(SortDirection _sDir, string _sItem)
{
//TODO: Add logic to look at _sItem and decide what property to sort on
IEnumerable<ScoutItem> si_enum = this.AsEnumerable();
if (_sDir == SortDirection.Ascending)
{
si_enum = si_enum.OrderBy(p => p.UPC).AsEnumerable();
} else
{
si_enum = si_enum.OrderByDescending(p => p.UPC).AsEnumerable();
}
foreach (ScoutItem si in si_enum)
{
int _OldIndex = this.IndexOf(si);
int _NewIndex = si_enum.ToList().IndexOf(si);
this.MoveItem(_OldIndex, _NewIndex);
}
}
}
var collection = new SortingObservableCollection<MyViewModel, int>(Comparer<int>.Default, model => model.IntPropertyToSortOn);
collection.Add(new MyViewModel(3));
collection.Add(new MyViewModel(1));
collection.Add(new MyViewModel(2));
// At this point, the order is 1, 2, 3
collection[0].IntPropertyToSortOn = 4; // As long as IntPropertyToSortOn uses INotifyPropertyChanged, this will cause the collection to resort correctly
public static void Sort<T>(this ObservableCollection<T> collection, Func<T,T> keySelector) where T : IComparable
{
List<T> sorted = collection.OrderBy(keySelector).ToList();
for (int i = 0; i < sorted.Count(); i++)
collection.Move(collection.IndexOf(sorted[i]), i);
}
myCollection = new ObservableCollection<MyObject>();
//Sorts in place, on a specific Func<T,T>
myCollection.Sort(x => x.ID);
static class Extensions
{
public static void Sort<TSource, TKey>(this ObservableCollection<TSource> collection, Func<TSource, TKey> keySelector)
{
List<TSource> sorted = collection.OrderBy(keySelector).ToList();
for (int i = 0; i < sorted.Count(); i++)
collection.Move(collection.IndexOf(sorted[i]), i);
}
}
myObservableCollection.Sort(o => o.MyProperty);
// SortableObservableCollection
public class SortableObservableCollection<T> : ObservableCollection<T>
{
public SortableObservableCollection(List<T> list)
: base(list)
{
}
public SortableObservableCollection()
{
}
public void Sort<TKey>(Func<T, TKey> keySelector, System.ComponentModel.ListSortDirection direction)
{
switch (direction)
{
case System.ComponentModel.ListSortDirection.Ascending:
{
ApplySort(Items.OrderBy(keySelector));
break;
}
case System.ComponentModel.ListSortDirection.Descending:
{
ApplySort(Items.OrderByDescending(keySelector));
break;
}
}
}
public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
{
ApplySort(Items.OrderBy(keySelector, comparer));
}
private void ApplySort(IEnumerable<T> sortedItems)
{
var sortedItemsList = sortedItems.ToList();
foreach (var item in sortedItemsList)
{
Move(IndexOf(item), sortedItemsList.IndexOf(item));
}
}
}
MySortableCollection.Sort(x => x, System.ComponentModel.ListSortDirection.Ascending);
/// <summary>
/// Synches the collection items to the target collection items.
/// This does not observe sort order.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The items.</param>
/// <param name="updatedCollection">The updated collection.</param>
public static void SynchCollection<T>(this IList<T> source, IEnumerable<T> updatedCollection)
{
// Evaluate
if (updatedCollection == null) return;
// Make a list
var collectionArray = updatedCollection.ToArray();
// Remove items from FilteredViewItems not in list
source.RemoveRange(source.Except(collectionArray));
// Add items not in FilteredViewItems that are in list
source.AddRange(collectionArray.Except(source));
}
/// <summary>
/// Synches the collection items to the target collection items.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="updatedCollection">The updated collection.</param>
/// <param name="canSort">if set to <c>true</c> [can sort].</param>
public static void SynchCollection<T>(this ObservableCollection<T> source,
IList<T> updatedCollection, bool canSort = false)
{
// Synch collection
SynchCollection(source, updatedCollection.AsEnumerable());
// Sort collection
if (!canSort) return;
// Update indexes as needed
for (var i = 0; i < updatedCollection.Count; i++)
{
// Index of new location
var index = source.IndexOf(updatedCollection[i]);
if (index == i) continue;
// Move item to new index if it has changed.
source.Move(index, i);
}
}
public ObservableCollection<string> MyStrings { get; set; }
private ListCollectionView _listCollectionView;
private void InitializeCollection()
{
MyStrings = new ObservableCollection<string>();
_listCollectionView = CollectionViewSource.GetDefaultView(MyStrings)
as ListCollectionView;
if (_listCollectionView != null)
{
_listCollectionView.IsLiveSorting = true;
_listCollectionView.CustomSort = new
CaseInsensitiveComparer(CultureInfo.InvariantCulture);
}
}
class MyObject
{
public int id { get; set; }
public string title { get; set; }
}
ObservableCollection<MyObject> myCollection = new ObservableCollection<MyObject>();
//add stuff to collection
// .
// .
// .
myCollection = new ObservableCollection<MyObject>(
myCollection.OrderBy(n => n.title, Comparer<string>.Create(
(x, y) => (Utils.Utils.LogicalStringCompare(x, y)))));
static class Extensions
{
public static void Sort<T, TKey>(this ObservableCollection<T> collection, Func<ObservableCollection<T>, TKey> sort)
{
var sorted = (sort.Invoke(collection) as IOrderedEnumerable<T>).ToArray();
for (int i = 0; i < sorted.Count(); i++)
collection.Move(collection.IndexOf(sorted[i]), i);
}
}
Children.Sort(col => col.OrderByDescending(xx => xx.ItemType == "drive")
.ThenByDescending(xx => xx.ItemType == "folder")
.ThenBy(xx => xx.Path));
public static void Sort<TSource, TKey>(this ObservableCollection<TSource> collection, Func<TSource, TKey> keySelector)
{
List<TSource> sorted = collection.OrderBy(keySelector).ToList();
Dictionary<TSource, int> indexOf = new Dictionary<TSource, int>();
for (int i = 0; i < sorted.Count; i++)
indexOf[sorted[i]] = i;
int idx = 0;
while (idx < sorted.Count)
if (!collection[idx].Equals(sorted[idx])) {
int newIdx = indexOf[collection[idx]]; // where should current item go?
collection.Move(newIdx, idx); // move whatever's there to current location
collection.Move(idx + 1, newIdx); // move current item to proper location
}
else {
idx++;
}
}