c# Metro (Windows Store)保持ListView排序
本文关键字:保持 ListView 排序 Store Metro Windows | 更新日期: 2023-09-27 18:18:13
保持一个ObservableCollection绑定到ListView按字母顺序排序是一个很好的解决方案?似乎是Windows 8。x不提供CollectionViewSource上的排序,所以我需要对ObservableCollection进行排序。
集合需要在适当的排序顺序,每次一个字符串被添加到它,所以我相信我需要的是一个方法来插入数据到适当的位置,而不是将其添加到ObservableCollection,然后排序的集合,但我还没有找到一个好方法来做到这一点。
一种不影响整个集合的插入方法是首先找到新条目插入的索引,然后使用内置的Insert
将其添加到集合中。
在这种情况下,扩展方法将是完美的。
public static void InsertInOrder<T>(this IList<T> list, T newItem, IComparer<T> comparer = null)
{
comparer = comparer ?? Comparer<T>.Default;
var index = Array.BinarySearch<T>(list.ToArray<T>(), newItem, comparer);
if (index >= 0)
{
throw new ArgumentException("Cannot insert duplicated items");
}
else
{
list.Insert(~index, newItem);
}
}
确保你有一个这样的集合,
ObservableCollection<string> _collection = new ObservableCollection<string> { "a", "b", "c", "e", "f" };
然后调用扩展方法,执行
_collection.InsertInOrder("d");
希望这对你有帮助!
ObservableCollection<T>
实现了IList<T>
,因此每次需要添加内容时,您可以将其作为列表进行二进制搜索,并在适当的位置插入:
public static class ListHelper
{
public static int BinarySearchFirst<T>(this IList<T> list, T item, IComparer<T> comparer)
{
comparer = comparer ?? Comparer<T>.Default;
int start = list.BinarySearch(item, comparer);
for (; start > 0 && comparer.Compare(list[start], list[start - 1]) == 0; start--)
;
return start;
}
public static int BinarySearchLast<T>(this IList<T> list, T item, IComparer<T> comparer)
{
comparer = comparer ?? Comparer<T>.Default;
int start = list.BinarySearch(item, comparer);
if (start > 0)
{
for (int end = list.Count - 1; start < end && comparer.Compare(list[start], list[start + 1]) == 0; start++)
;
}
return start;
}
public static int BinarySearch<T>(this IList<T> list, T value)
{
return BinarySearch(list, value, null);
}
// Searches the list for a given element using a binary search
// algorithm. Elements of the list are compared to the search value using
// the given IComparer interface. If comparer is null, elements of
// the list are compared to the search value using the IComparable
// interface, which in that case must be implemented by all elements of the
// list and the given search value. This method assumes that the given
// section of the list is already sorted; if this is not the case, the
// result will be incorrect.
//
// The method returns the index of the given value in the list. If the
// list does not contain the given value, the method returns a negative
// integer. The bitwise complement operator (~) can be applied to a
// negative result to produce the index of the first element (if any) that
// is larger than the given search value. This is also the index at which
// the search value should be inserted into the list in order for the list
// to remain sorted.
public static int BinarySearch<T>(this IList<T> list, T value, IComparer<T> comparer)
{
// Adapted from http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs
if (list == null)
throw new ArgumentNullException("list");
comparer = comparer ?? Comparer<T>.Default;
int lo = 0;
int hi = list.Count - 1;
while (lo <= hi)
{
int i = lo + ((hi - lo) >> 1);
int order = comparer.Compare(list[i], value);
if (order == 0)
return i;
if (order < 0)
{
lo = i + 1;
}
else
{
hi = i - 1;
}
}
return ~lo;
}
public static int AddToSortedList<T>(this IList<T> list, T value, bool allowDuplicates)
{
return list.AddToSortedList(value, allowDuplicates, null);
}
public static int AddToSortedList<T>(this IList<T> list, T value, bool allowDuplicates, IComparer<T> comparer)
{
// If the incoming value is equivalent to the some value already in the list using the current comparer,
// add it to the END of the sequence of equivalent entries.
int index = list.BinarySearchLast(value, comparer);
if (!allowDuplicates && index >= 0)
return index;
if (index < 0)
index = ~index;
list.Insert(index, value);
return index;
}
}
这是有争议的AddToSortedList()
是否应该是一个扩展方法或只是一些静态助手方法,因为许多列表将不排序。如果尝试向列表中添加与某些预先存在的条目相等的条目,我的方法将新条目添加到等效条目序列的末尾,或者返回调用者指定的现有条目的索引。根据您的需要,您可能更喜欢抛出一个异常。