排序可观察集合<;字符串>;通过C#

排序可观察集合<;字符串>;通过C#,c#,sorting,observablecollection,C#,Sorting,Observablecollection,我有以下可观察到的收集。我需要按字母顺序对这个进行排序 private ObservableCollection<string> _animals = new ObservableCollection<string> { "Cat", "Dog", "Bear", "Lion", "Mouse", "Horse", "Rat", "Elephant", "Kangaroo", "Lizard", "Snake", "Frog", "Fish",

我有以下
可观察到的收集
。我需要按字母顺序对这个进行排序

private ObservableCollection<string> _animals = new ObservableCollection<string>
{
    "Cat", "Dog", "Bear", "Lion", "Mouse",
    "Horse", "Rat", "Elephant", "Kangaroo", "Lizard", 
    "Snake", "Frog", "Fish", "Butterfly", "Human", 
    "Cow", "Bumble Bee"
};

如何执行此操作?

OrderByDescending的参数是一个函数,它返回一个要排序的键。在您的情况下,键是字符串本身:

var result = _animals.OrderByDescending(a => a);
例如,如果您想按长度排序,您将编写:

var result = _animals.OrderByDescending(a => a.Length);

OrderByDescending
的参数是一个返回要排序的键的函数。在您的情况下,键是字符串本身:

var result = _animals.OrderByDescending(a => a);
例如,如果您想按长度排序,您将编写:

var result = _animals.OrderByDescending(a => a.Length);
介绍

基本上,如果需要显示排序集合,请考虑使用<代码> CollectionViewSource <代码>类:将其“代码>源代码属性指定(“绑定”)到源集合- <代码> 想法是这样的。这是原始(源)集合的一种“投影”,但应用了排序、过滤等

参考资料:

活形 WPF 4.5为
CollectionViewSource
引入了“实时成型”功能

参考资料:

解决方案 如果仍然需要对
ObservaleCollection
类的实例进行排序,下面介绍如何进行排序。
ObservableCollection
类本身没有排序方法。但是,可以重新创建集合以对项目进行排序:

// Animals property setter must raise "property changed" event to notify binding clients.
// See INotifyPropertyChanged interface for details.
Animals = new ObservableCollection<string>
    {
        "Cat", "Dog", "Bear", "Lion", "Mouse",
        "Horse", "Rat", "Elephant", "Kangaroo",
        "Lizard", "Snake", "Frog", "Fish",
        "Butterfly", "Human", "Cow", "Bumble Bee"
    };
...
Animals = new ObservableCollection<string>(Animals.OrderBy(i => i));
//属性设置程序必须引发“属性已更改”事件以通知绑定客户端。
//有关详细信息,请参见INotifyPropertyChanged接口。
动物=新观察到的集合
{
“猫”、“狗”、“熊”、“狮子”、“老鼠”,
“马”、“老鼠”、“大象”、“袋鼠”,
“蜥蜴”、“蛇”、“青蛙”、“鱼”,
“蝴蝶”、“人”、“牛”、“大黄蜂”
};
...
动物=新的可观察到的集合(动物.OrderBy(i=>i));
其他细节 请注意,
OrderBy()
OrderByDescending()
方法(与其他LINQ–扩展方法一样)不修改源集合!相反,它们创建一个新序列(即实现
IEnumerable
接口的类的新实例)。因此,有必要重新创建集合。

简介
_animals.OrderByDescending(a => a.<what_is_here_?>);

基本上,如果需要显示排序集合,请考虑使用<代码> CollectionViewSource <代码>类:将其“代码>源代码属性指定(“绑定”)到源集合- <代码> 想法是这样的。这是原始(源)集合的一种“投影”,但应用了排序、过滤等

参考资料:

活形 WPF 4.5为
CollectionViewSource
引入了“实时成型”功能

参考资料:

解决方案 如果仍然需要对
ObservaleCollection
类的实例进行排序,下面介绍如何进行排序。
ObservableCollection
类本身没有排序方法。但是,可以重新创建集合以对项目进行排序:

// Animals property setter must raise "property changed" event to notify binding clients.
// See INotifyPropertyChanged interface for details.
Animals = new ObservableCollection<string>
    {
        "Cat", "Dog", "Bear", "Lion", "Mouse",
        "Horse", "Rat", "Elephant", "Kangaroo",
        "Lizard", "Snake", "Frog", "Fish",
        "Butterfly", "Human", "Cow", "Bumble Bee"
    };
...
Animals = new ObservableCollection<string>(Animals.OrderBy(i => i));
//属性设置程序必须引发“属性已更改”事件以通知绑定客户端。
//有关详细信息,请参见INotifyPropertyChanged接口。
动物=新观察到的集合
{
“猫”、“狗”、“熊”、“狮子”、“老鼠”,
“马”、“老鼠”、“大象”、“袋鼠”,
“蜥蜴”、“蛇”、“青蛙”、“鱼”,
“蝴蝶”、“人”、“牛”、“大黄蜂”
};
...
动物=新的可观察到的集合(动物.OrderBy(i=>i));
其他细节 请注意,
OrderBy()
OrderByDescending()
方法(与其他LINQ–扩展方法一样)不修改源集合!相反,它们创建一个新序列(即实现
IEnumerable
接口的类的新实例)。因此,有必要重新创建集合。

\u animals.OrderByDescending(a=>a.);
_animals.OrderByDescending(a => a.<what_is_here_?>);
如果动物是对象动物的列表,则可以使用属性对列表进行排序

public class Animal
{
    public int ID {get; set;}
    public string Name {get; set;}
    ...
}

ObservableCollection<Animal> animals = ...
animals = animals.OrderByDescending(a => a.Name);
公共类动物
{
公共int ID{get;set;}
公共字符串名称{get;set;}
...
}
可观察收集动物=。。。
动物=动物.OrderByDescending(a=>a.Name);
\u动物。按降序排列(a=>a);
如果动物是对象动物的列表,则可以使用属性对列表进行排序

public class Animal
{
    public int ID {get; set;}
    public string Name {get; set;}
    ...
}

ObservableCollection<Animal> animals = ...
animals = animals.OrderByDescending(a => a.Name);
公共类动物
{
公共int ID{get;set;}
公共字符串名称{get;set;}
...
}
可观察收集动物=。。。
动物=动物.OrderByDescending(a=>a.Name);

我知道这是一个老问题,但这是“sort observablecollection”的第一个谷歌结果,所以我认为留下我的两分钱是值得的

路途 我要做的是从
ObservableCollection
开始构建一个
列表
,对它进行排序(通过它的
sort()
方法),当
列表
被排序后,用
Move()
方法对
ObservableCollection
重新排序

代码
publicstaticvoidsort(此ObservableCollection集合,比较)
{
var sortableList=新列表(集合);
可排序列表。排序(比较);
for(int i=0;i
测试
public void TestObservableCollectionSortExtension()
{
var observableCollection=新的observableCollection();
var maxValue=10;
//以反向模式填充列表[maxValue,maxValue-1,…,1,0]
对于(int i=maxValue;i>=0;i--)
{
增加(i);
}
//断言集合处于反向模式
对于(int i=maxValue;i>=0;i--)
{
主张平等(i,
public static void MySort<TSource,TKey>(this ObservableCollection<TSource> observableCollection, Func<TSource, TKey> keySelector)
    {
        var a = observableCollection.OrderBy(keySelector).ToList();
        observableCollection.Clear();
        foreach(var b in a)
        {
            observableCollection.Add(b);
        }
    }
myObservableCollection.ToList().Sort((x, y) => x.Property.CompareTo(y.Property));
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;

namespace ConsoleApp4
{
  using static Console;

  public class SortableObservableCollection<T> : ObservableCollection<T>
  {
    public Func<T, object> SortingSelector { get; set; }
    public bool Descending { get; set; }
    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
      base.OnCollectionChanged(e);
      if (SortingSelector == null 
          || e.Action == NotifyCollectionChangedAction.Remove
          || e.Action == NotifyCollectionChangedAction.Reset)
        return;

      var query = this
        .Select((item, index) => (Item: item, Index: index));
      query = Descending
        ? query.OrderBy(tuple => SortingSelector(tuple.Item))
        : query.OrderByDescending(tuple => SortingSelector(tuple.Item));

      var map = query.Select((tuple, index) => (OldIndex:tuple.Index, NewIndex:index))
       .Where(o => o.OldIndex != o.NewIndex);

      using (var enumerator = map.GetEnumerator())
       if (enumerator.MoveNext())
          Move(enumerator.Current.OldIndex, enumerator.Current.NewIndex);


    }
  }


  //USAGE
  class Program
  {
    static void Main(string[] args)
    {
      var xx = new SortableObservableCollection<int>() { SortingSelector = i => i };
      xx.CollectionChanged += (sender, e) =>
       WriteLine($"action: {e.Action}, oldIndex:{e.OldStartingIndex},"
         + " newIndex:{e.NewStartingIndex}, newValue: {xx[e.NewStartingIndex]}");

      xx.Add(10);
      xx.Add(8);
      xx.Add(45);
      xx.Add(0);
      xx.Add(100);
      xx.Add(-800);
      xx.Add(4857);
      xx.Add(-1);

      foreach (var item in xx)
        Write($"{item}, ");
    }
  }
}
action: Add, oldIndex:-1, newIndex:0, newValue: 10
action: Add, oldIndex:-1, newIndex:1, newValue: 8
action: Move, oldIndex:1, newIndex:0, newValue: 8
action: Add, oldIndex:-1, newIndex:2, newValue: 45
action: Add, oldIndex:-1, newIndex:3, newValue: 0
action: Move, oldIndex:3, newIndex:0, newValue: 0
action: Add, oldIndex:-1, newIndex:4, newValue: 100
action: Add, oldIndex:-1, newIndex:5, newValue: -800
action: Move, oldIndex:5, newIndex:0, newValue: -800
action: Add, oldIndex:-1, newIndex:6, newValue: 4857
action: Add, oldIndex:-1, newIndex:7, newValue: -1
action: Move, oldIndex:7, newIndex:1, newValue: -1
-800, -1, 0, 8, 10, 45, 100, 4857,
public class RateInfo 
{
    public string begin { get; set; }
    public string end { get; set; }
    public string price { get; set; }
    public string comment { get; set; }
    public string phone { get; set; }
    public string ImagePath { get; set; }
    public string what { get; set; }
    public string distance { get; set; }
}    

public ObservableCollection<RateInfo> Phones { get; set; }

public List<RateInfo> LRate { get; set; }

public ObservableCollection<RateInfo> Phones { get; set; }

public List<RateInfo> LRate { get; set; }

......

foreach (var item in ph)
        {

            LRate.Add(new RateInfo { begin = item["begin"].ToString(), end = item["end"].ToString(), price = item["price"].ToString(), distance=kilom, ImagePath = "chel.png" });
        }

       LRate.Sort((x, y) => x.distance.CompareTo(y.distance));

        foreach (var item in LRate)
        {
            Phones.Add(item);
        }
// Call on dispatcher.
ObservableCollection<MyClass> collectionView = new ObservableCollection<MyClass>();
var p1 = new MyClass() { Key = "A" }
var p2 = new MyClass() { Key = "Z" }
var p3 = new MyClass() { Key = "D" }
collectionView.InsertInPlace(p1, o => o.Key);
collectionView.InsertInPlace(p2, o => o.Key);
collectionView.InsertInPlace(p3, o => o.Key);
// The list will always remain ordered on the screen, e.g. "A, D, Z" .
// Insertion speed is Log(N) as it uses a binary search.
/// <summary>
/// Inserts an item into a list in the correct place, based on the provided key and key comparer. Use like OrderBy(o => o.PropertyWithKey).
/// </summary>
public static void InsertInPlace<TItem, TKey>(this ObservableCollection<TItem> collection, TItem itemToAdd, Func<TItem, TKey> keyGetter)
{
    int index = collection.ToList().BinarySearch(keyGetter(itemToAdd), Comparer<TKey>.Default, keyGetter);
    collection.Insert(index, itemToAdd);
}
/// <summary>
/// Binary search.
/// </summary>
/// <returns>Index of item in collection.</returns> 
/// <notes>This version tops out at approximately 25% faster than the equivalent recursive version. This 25% speedup is for list
/// lengths more of than 1000 items, with less performance advantage for smaller lists.</notes>
public static int BinarySearch<TItem, TKey>(this IList<TItem> collection, TKey keyToFind, IComparer<TKey> comparer, Func<TItem, TKey> keyGetter)
{
    if (collection == null)
    {
        throw new ArgumentNullException(nameof(collection));
    }

    int lower = 0;
    int upper = collection.Count - 1;

    while (lower <= upper)
    {
        int middle = lower + (upper - lower) / 2;
        int comparisonResult = comparer.Compare(keyToFind, keyGetter.Invoke(collection[middle]));
        if (comparisonResult == 0)
        {
            return middle;
        }
        else if (comparisonResult < 0)
        {
            upper = middle - 1;
        }
        else
        {
            lower = middle + 1;
        }
    }

    // If we cannot find the item, return the item below it, so the new item will be inserted next.
    return lower;
}
public class SortedObservableCollection<T> : ObservableCollection<T> where T : IComparable<T>
{
    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        base.OnCollectionChanged(e);
        if (e.Action != NotifyCollectionChangedAction.Reset &&
            e.Action != NotifyCollectionChangedAction.Move &&
            e.Action != NotifyCollectionChangedAction.Remove)
        {
            var query = this.Select((item, index) => (Item: item, Index: index)).OrderBy(tuple => tuple.Item, Comparer.Default);
            var map = query.Select((tuple, index) => (OldIndex: tuple.Index, NewIndex: index)).Where(o => o.OldIndex != o.NewIndex);
            using (var enumerator = map.GetEnumerator())
            {
                if (enumerator.MoveNext())
                {
                    base.MoveItem(enumerator.Current.OldIndex, enumerator.Current.NewIndex);
                }
            }
        }
    }

    // (optional) user is not allowed to move items in a sorted collection
    protected override void MoveItem(int oldIndex, int newIndex) => throw new InvalidOperationException();
    protected override void SetItem(int index, T item) => throw new InvalidOperationException();

    private class Comparer : IComparer<T>
    {
        public static readonly Comparer Default = new Comparer();

        public int Compare(T x, T y) => x.CompareTo(y);
    }

    // explicit sort; sometimes needed.
    public virtual void Sort()
    {
        if (Items.Count <= 1)
            return;

        var items = Items.ToList();
        Items.Clear();
        items.Sort();
        foreach (var item in items)
        {
            Items.Add(item);
        }
        OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }
}
namespace YourNameSpace
{
    public static class ObservableCollectionExtension
    {
        public static void OrderByReference<T>(this ObservableCollection<T> collection, List<T> comparison)
        {
            for (int i = 0; i < comparison.Count; i++)
            {
                if (!comparison.ElementAt(i).Equals(collection.ElementAt(i)))
                    collection.Move(collection.IndexOf(comparison[i]), i);
            }
        }
        
        public static void InsertInPlace<T>(this ObservableCollection<T> collection, List<T> comparison, T item)
        {
            int index = comparison.IndexOf(item);
            comparison.RemoveAt(index);
            collection.OrderByReference(comparison);
            collection.Insert(index, item);
        }
    }
}
_animals.OrderByReference(_animals.OrderBy(x => x).ToList());
public static void OrderByReference<T>(this ObservableCollection<T> collection, List<T> comparison)
{
    for (int i = 0; i < comparison.Count; i++)
    {
        collection.Move(collection.IndexOf(comparison[i]), i);
    }
}
YourObservableCollection.OrderByReference(YourObservableCollection.DoYourLinqOrdering().ToList());
public static void InsertInPlace<T>(this ObservableCollection<T> collection, List<T> comparison, T item)
{
    collection.Insert(comparison.IndexOf(item), item);
}
var YourList = YourObservableCollection.ToList();
var YourObject = new YourClass { ..... };
YourList.Add(YourObject);
YourObservableCollection.InsertInPlace(YourList.DoYourLinqOrdering().ToList(), YourObject);
public static void Sort<T>(this ObservableCollection<T> list) where T : IComparable<T>
{
    int i = 0;
    foreach (var item in list.OrderBy(x => x))
    {
        if (!item.Equals(list[i]))
        {
            list[i] = item;
        }

        i++;
    }
}