SortableBindingList

   ソート用のバインディングリストです。
第2キーを設定したい場合には以下のように使用します。

// Nameがソートされる際はIdでソートするようにソート方法変更
var idCompare = new Dictionary<string, IComparer<Data>>
{
   {"Name", ComparerUtils.By((Data r) => r.Id)}
};
 
//ソートの条件
var sortCompare = ComparerUtils.By((Data r) => r.Date).Append(ComparerUtils.By((Data r) => r.Name));

// 検索データの設定
this.dgvList.DataSource = null;
this.dgvList.DataSource = new SortableBindingList<Data>(filterList, sortCompare);

↓↓↓↓↓↓↓↓↓↓↓↓

     /// <summary>
    /// ソート用の拡張バインディングリスト
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SortableBindingList<T> :BindingList<T>
    {
        /// <summary>
        /// ソート項目
        /// </summary>
        private PropertyDescriptor _sortProp;
        /// <summary>
        /// ソート方向(昇順・降順)の保持を行います。
        /// </summary>
        private ListSortDirection _sortDir = ListSortDirection.Ascending;
        /// <summary>
        /// ソート済みかを示す値
        /// </summary>
        private bool _isSorted;

        /// <summary>
        /// 最優先比較オブジェクト
        /// </summary>
        private readonly Dictionary<string, IComparer<T>> _prioritySort;

        /// <summary>
        /// 第2キーの追加比較オブジェクト
        /// </summary>
        private readonly IComparer<T> _baseComparer;
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public SortableBindingList()
        {
            
        }
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public SortableBindingList(IList<T> list)
            : this(list,null)
        {
            
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public SortableBindingList(IList<T> list,IComparer<T> baseComparer)
            : this(list, baseComparer,null)
        {
            _baseComparer = baseComparer;
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public SortableBindingList(IList<T> list, IComparer<T> baseComparer, Dictionary<string, IComparer<T>> prioritySort)
            : base(list)
        {
            _baseComparer = baseComparer;
            _prioritySort = prioritySort;
        }

        public void ResetSort()
        {
            _sortProp = null;
            _sortDir = ListSortDirection.Ascending;
            _isSorted = false;
        }

        /// <summary>
        /// ソート処理
        /// </summary>
        /// <param name="property">ソート項目</param>
        /// <param name="direction">ソート方向</param>
        protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
        {
            var list = this.Items as List<T>;
            if (list != null)
            {
              
                // 比較処理を実行します。
                IComparer<T> compare;
                if (_prioritySort != null && _prioritySort.ContainsKey(property.DisplayName))
                {
                    // 比較オブジェクトの取得
                    compare = direction == ListSortDirection.Ascending ? _prioritySort[property.DisplayName] : _prioritySort[property.DisplayName].Reverse();
                }
                else
                {
                    // 比較オブジェクト作成
                    compare = PropertyComparerFactory.Factory<T>(property, direction);
                }

                // 比較処理を実行します。
                list.Sort(_baseComparer == null ? compare : compare.Append(_baseComparer));


                // ソート処理の終了を設定
                this._isSorted = true;
                this._sortProp = property;
                this._sortDir = direction;

                this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
            }
        }

        /// <summary>
        /// ソートのサポートを行う事を宣言
        /// </summary>
        protected override bool SupportsSortingCore
        {
            get { return true; }
        }
        /// <summary>
        /// 削除処理用
        /// </summary>
        protected override void RemoveSortCore()
        {
            
        }
        /// <summary>
        /// ソート済みかを示す値の取得用
        /// </summary>
        protected override bool IsSortedCore
        {
            get { return this._isSorted; }
        }

        /// <summary>
        /// ソート対象
        /// </summary>
        protected override PropertyDescriptor SortPropertyCore
        {
            get { return this._sortProp; }
        }
        /// <summary>
        /// ソート方向(昇順・降順)の保持を行います。
        /// </summary>
        protected override ListSortDirection SortDirectionCore
        {
            get { return this._sortDir; }
        }
    }



    /// <summary>
    /// ソート用のクラス
    /// </summary>
    public static class PropertyComparerFactory
    {
        public static IComparer<T> Factory<T>(PropertyDescriptor property, ListSortDirection direction)
        {
            var seed = typeof(PropertyComparer<,>);
            Type[] typeArgs = { typeof(T), property.PropertyType };
            var pcType = seed.MakeGenericType(typeArgs);
         
            var comparer = (IComparer<T>)Activator.CreateInstance(pcType, new object[] { property, direction });
            return comparer;
        }
    }

    /// <summary>
    /// 比較クラス
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="U"></typeparam>
    public sealed class PropertyComparer<T, U> : IComparer<T>
    {
        private readonly PropertyDescriptor _property;
        private readonly ListSortDirection _direction;
        private readonly Comparer<U> _comparer;

        public PropertyComparer(PropertyDescriptor property, ListSortDirection direction)
        {
            this._property = property;
            this._direction = direction;
            this._comparer = Comparer<U>.Default;
        }

        public int Compare(T x, T y)
        {
            var xValue = (U)this._property.GetValue(x);
            var yValue = (U)this._property.GetValue(y);


            if (this._direction == ListSortDirection.Ascending)
                return this._comparer.Compare(xValue, yValue);
            else
                return this._comparer.Compare(yValue, xValue);
        }
    }


 
  /// <summary>
    /// IComparer[T]補助関数
    /// </summary>
    public static class ComparerUtils
    {
        /// <summary>
        /// 動的にデリゲートから生成するIComparer[T]実装
        /// </summary>
        /// <typeparam name="T">比較対象の型</typeparam>
        private sealed class DynamicComparer<T> : IComparer<T>
        {
            private readonly Func<T, T, int> _compare;

            /// <summary>
            ///  2 つのオブジェクトを比較し、一方が他方より小さいか、等しいか、大きいかを示す値を返します。
            /// </summary>
            /// <param name="x">比較する最初のオブジェクトです。</param>
            /// <param name="y">比較する 2 番目のオブジェクト。</param>
            /// <returns>
            /// x と y の相対的な値を示す符号付き整数 (次の表を参照)。
            /// 値 : 説明
            /// number < 0 : x が y より小さい。
            /// 0 : x と y は等しい。
            /// 0 より大 : x が y より大きい。
            /// </returns>
            public int Compare(T x, T y)
            {

                return _compare(x, y);
            }

            /// <summary>
            /// コンストラクタ
            /// </summary>
            /// <param name="compare">比較関数</param>
            public DynamicComparer(Func<T, T, int> compare)
            {
                this._compare = compare;
            }
        }

        /// <summary>
        /// 比較するキーを指定してComparerを生成します。
        /// </summary>
        /// <typeparam name="T">比較対象の型</typeparam>
        /// <typeparam name="TP">キーの型</typeparam>
        /// <param name="selector">比較対象からキーを取得する関数</param>
        /// <param name="comparer">キーのComparer</param>
        /// <returns>Comparer</returns>
        public static IComparer<T> By<T, TP>(Func<T, TP> selector, IComparer<TP> comparer)
        {
            return new DynamicComparer<T>((x, y) => comparer.Compare(selector(x), selector(y)));
        }

        /// <summary>
        /// 比較するキーを指定してComparerを生成します。比較にはComparer[TP].Defaultを使用します
        /// </summary>
        /// <typeparam name="T">比較対象の型</typeparam>
        /// <typeparam name="TP">キーの型</typeparam>
        /// <param name="selector">比較対象からキーを取得する関数</param>
        /// <returns>Comparer</returns>
        public static IComparer<T> By<T, TP>(Func<T, TP> selector)
            where TP : IComparable<TP>
        {
            return By(selector, Comparer<TP>.Default);
        }

        /// <summary>
        /// Comparerでの比較結果が同一だった場合に、第二引数のComparerで比較を行うようなComparerを生成します
        /// </summary>
        /// <typeparam name="T">比較対象の型</typeparam>
        /// <param name="comparer">優先する第一のComparer</param>
        /// <param name="second">第二のComparer</param>
        /// <returns>Comparer</returns>
        public static IComparer<T> Append<T>(this IComparer<T> comparer, IComparer<T> second)
        {
            return new DynamicComparer<T>((x, y) =>
            {
                var first = comparer.Compare(x, y);
                if (first != 0)
                {
                    return first;
                }
                return second.Compare(x, y);
            });
        }

        /// <summary>
        /// Comparerの比較順序を逆転させます
        /// </summary>
        /// <typeparam name="T">比較対象の型</typeparam>
        /// <param name="comparer">元となるComparer</param>
        /// <returns>Comparer</returns>
        public static IComparer<T> Reverse<T>(this IComparer<T> comparer)
        {
            return new DynamicComparer<T>((x, y) => comparer.Compare(y, x));
        }
    }