我怎么排序可观察集合? [英] How do I sort an observable collection?

查看:277
本文介绍了我怎么排序可观察集合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的类:

[DataContract]
public class Pair<TKey, TValue> : INotifyPropertyChanged, IDisposable
{
    public Pair(TKey key, TValue value)
    {
        Key = key;
        Value = value;
    }

    #region Properties
    [DataMember]
    public TKey Key
    {
        get
        { return m_key; }
        set
        {
            m_key = value;
            OnPropertyChanged("Key");
        }
    }
    [DataMember]
    public TValue Value
    {
        get { return m_value; }
        set
        {
            m_value = value;
            OnPropertyChanged("Value");
        }
    }
    #endregion

    #region Fields
    private TKey m_key;
    private TValue m_value;
    #endregion

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    #endregion

    #region IDisposable Members

    public void Dispose()
    { }

    #endregion
}

我已经放在一个ObservableCollection:

Which I've put in an ObservableCollection :

ObservableCollection<Pair<ushort, string>> my_collection = 
    new ObservableCollection<Pair<ushort, string>>();

my_collection.Add(new Pair(7, "aaa"));
my_collection.Add(new Pair(3, "xey"));
my_collection.Add(new Pair(6, "fty"));

问:如何通过按键排序

Q : How do I sort it by key ?

推荐答案

OP编辑:正如许多人正确地指出了原来的答案不返回相同的集合,(原来更关注排序的字典部分Q)。请参阅编辑在底部,我解决可观察集合的排序。这里原为左仍然收到了票

您可以使用LINQ作为doSort方法如下所示。快速code片断:产生

You can use linq as the doSort method below illustrates. A quick code snippet: produces

3:xey 6:FTY 7:AAA

3:xey 6:fty 7:aaa

另外,您可以使用集合本身的扩展方法

Alternatively you could use an extension method on the collection itself

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;
    }
}

修改

要返回一个ObservableCollection,呼吁.ToObservableCollection上的 sortedOC 的使用,例如这个实现

To return an ObservableCollection, call .ToObservableCollection on sortedOC using e.g. this implementation.

OP修改 排序可观察并返回同一对象进行排序可以使用扩展方法来完成。对于较大的集合注意收集一些改变的通知,例如

OP EDIT Sorting an observable and returning the same object sorted can be done using an extension method. For larger collections watch out for the number of collection changed notifications eg

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++;
            }
        }
    }

用法: 样品与观察者(用Person类保持简单)

usage: Sample with an observer (used a Person class to keep it simple)

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();
    };

从上面的输出:
去掉凯蒂51岁,在指数0
加入凯蒂51岁,在指数8
去掉玛丽41岁,在指数3
加入玛丽41岁,在指数7
去掉珍20岁,在指数3
加珍20岁,在指数5
去掉吉姆39岁,在指数3
加入吉姆39岁,在指数6
去掉珍20岁,在指数4
加珍20岁,在指数5

Output from above:
removed Katy aged 51 at index 0
added Katy aged 51 at index 8
removed Mary aged 41 at index 3
added Mary aged 41 at index 7
removed Jane aged 20 at index 3
added Jane aged 20 at index 5
removed Jim aged 39 at index 3
added Jim aged 39 at index 6
removed Jane aged 20 at index 4
added Jane aged 20 at index 5

Person类同时实现了IComparable接口和IEquatable后者用于最小化更改收集,以减少引发更改通知的数量

The Person class implements both IComparable and IEquatable the latter is used to minimise the changes to the collection so as to reduce the number of change notifications raised

这篇关于我怎么排序可观察集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆