1

SortedList のラッパー クラスを作成しました。このクラスにオブジェクトを追加すると、自動的にアルファベット順に並べ替えられることを期待していますが、WPF で ListBox にバインドすると、並べ替えられていない順序で表示されます。

public class SortedObservableCollection<T> : ICollection<T>, INotifyPropertyChanged, INotifyCollectionChanged where T : INotifyPropertyChanged//, IComparable<T>
{
    private readonly SortedList<string,T> _innerSortedList;

    public SortedObservableCollection()
    {
        _innerSortedList = new SortedList<string, T>();
    }

    public void Add(T item)
    {
        _innerSortedList.Add(item.ToString(), item);
        this.OnPropertyChanged("Count");
        this.OnPropertyChanged("Item[]");
        this.OnCollectionChanged(NotifyCollectionChangedAction.Add, item);
        item.PropertyChanged += ItemPropertyChanged;
    }

    void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        throw new NotImplementedException();
    }

    public void Clear()
    {
        _innerSortedList.Clear();
    }

    public bool Contains(T item)
    {
        return _innerSortedList.ContainsKey(item.ToString());
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }

    public int Count
    {
        get { return _innerSortedList.Count; }
    }

    public bool IsReadOnly
    {
        get { throw new NotImplementedException(); }
    }

    public bool Remove(T item)
    {
        bool success = _innerSortedList.Remove(item.ToString());
        if (success)
        {
            item.PropertyChanged -= ItemPropertyChanged;
            this.OnPropertyChanged("Count");
            this.OnPropertyChanged("Item[]");
            this.OnCollectionChanged(NotifyCollectionChangedAction.Remove, item);
        }
        return success;
    }

    public IEnumerator<T> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _innerSortedList.GetEnumerator();
    }

    protected virtual void OnPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action, object item)
    {
        if (this.CollectionChanged != null)
        {
            this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, item));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public event NotifyCollectionChangedEventHandler CollectionChanged;
}

バインドするには、次のようにします。

SortedObservableCollection<IRCUser> Users { get; private set; }
.. fill users...
lstUsers.ItemsSource = users;

サンプル入力:

5Muhammad0
2Muhammad1
5Muhammad2

出力も同様で、2、4 などで始まるものは 5 の間でなぞられています。

注: 私IRCUserのクラスは IComparable を実装しましたが、今はアルファベット順の並べ替えのみが必要なので、既定の並べ替えが開始されることを期待して、実装をコメントアウトしました。

注2:言及するのを忘れていたtoString()メソッドをオーバーライドしました:

public override string ToString()
{
    return (int)Type + Nick;
}

アップデート :

内部的にsortedListは正しい順序を維持しているように見えますが、正しい順序で渡されていませんListBox...

4

4 に答える 4