ソート可能なデータソース


テキトーなカスタムクラスのデータソースクラス作ったら、グリッドでソートできなかったので、調べてみました。
http://codezine.jp/article/detail/1159?p=2
さすがは先人の知恵。
上図のようにソートできるようになりました。

IComparerって「プログラミングC#」で、ほけーと読んでたけど、便利ですね。

VBからC#への変換はツールがありそうだけど、手作業で作ってみました。

        #region //comparer

        public class SampleComparer : IComparer
        {
            private ListSortDirection _direction;   //ソートの向き(昇順/降順)
            private PropertyDescriptor _property;   //ソート項目

            public SampleComparer(PropertyDescriptor prop, ListSortDirection direction)
            {
                this._property = prop;
                this._direction = direction;
            }

            //同値の場合ゼロを返します。
            int IComparer.Compare(T objX, T objY)
            {
                //比較対象のオブジェクトからクリックしたプロパティを取得します。
                object valX = this.GetPropValue(objX, this._property.Name);
                object valY = this.GetPropValue(objY, this._property.Name);

                //directionの値(昇順/降順)に応じて取得した値を比較します。
                if (this._direction == ListSortDirection.Ascending)
                    return this.CompareAsc(valX, valY);
                else
                    return this.CompareDesc(valX, valY);
            }
            //昇順で比較を行います。
            private int CompareAsc(object valX, object valY)
            {
                return valX.ToString().CompareTo(valY.ToString());
            }

            //降順で比較を行います。
            private int CompareDesc(object valX, object valY)
            {
                return (this.CompareAsc(valX, valY) * -1);
            }

            //プロパティ値を取得します。
            private object GetPropValue(T val, string prop)
            {
                PropertyInfo propInfo = val.GetType().GetProperty(prop);
                return propInfo.GetValue(val, null);
            }

        }
        #endregion

        #region //BindingList
        public class SortBindingList : BindingList
        {

            private bool _isSorted; //ソート済みか否かを識別します。
            //ソート項目を保持します。
            private PropertyDescriptor _sortProperty;
            //ソート方向(昇順/降順)を保持します。
            private ListSortDirection _sortDirection;

            //リストをバインドします。
            public SortBindingList(T[] items)
            {
               
                *1;

            }
        }
        #endregion

あとは、Listなんかを、コンストラクタに渡して、グリッドのDataSourceに代入するだけでOKでした。

            this.view.DataSource = new SortBindingList(data.ToArray());

*1:List)base.Items).AddRange(items); } //ソートが可能であることを公開します。 //このプロパティがtrueで公開されないとソートが実行できません。 protected override bool SupportsSortingCore { get { return true; } } //ソートを実行します。 protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction) { //ソートするためバインドされているリストを取得します。 List items = base.Items as List; //リストがあった場合、 //Comparerを生成してソート項目と項目名を渡します。 if(items != null) { SampleComparer sc = new SampleComparer(prop, direction); items.Sort(sc); //ソート済みに設定します。 this._isSorted = true; } else { this._isSorted = false; } //ソート結果、方向を保持しておきます。 this._sortProperty = prop; this._sortDirection = direction; //リストが変更(ソート)されたことをイベント通知します。 this.OnListChanged(new ListChangedEventArgs( ListChangedType.ItemMoved, prop