DataGridViewでカスタムデータをソートする
ナビゲーションに移動
検索に移動
概要
DataGridViewでソートを可能にすることは簡単で、以下に記載するSortableBindingListをDataGridView.DataSourceへ設定するだけである。
下記にソースコードを記載する。
ソート可能なバインディングリスト
SortableBindingList.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sample { /// <summary> /// ソート可能なバインディングリストクラス /// </summary> /// <typeparam name="T">リスト内容</typeparam> public class SortableBindingList<T> : BindingList<T> where T : class { /// <summary> /// ソート済みかどうか /// </summary> private bool isSorted; /// <summary> /// 並べ替え操作の方向 /// </summary> private ListSortDirection sortDirection = ListSortDirection.Ascending; /// <summary> /// ソートを行う抽象化プロパティ /// </summary> private PropertyDescriptor sortProperty; /// <summary> /// SortableBindingList クラス の 新しいインスタンス を初期化します。 /// </summary> public SortableBindingList() { } /// <summary> /// 指定した リストクラス を利用して SortableBindingList クラス の 新しいインスタンス を初期化します。 /// </summary> /// <param name="list">SortableBindingList に格納される System.Collection.Generic.IList</param> public SortableBindingList(IList<T> list) : base(list) { } /// <summary> /// リストがソートをサポートしているかどうかを示す値を取得します。 /// </summary> protected override bool SupportsSortingCore { get { return true; } } /// <summary> /// リストがソートされたかどうかを示す値を取得します。 /// </summary> protected override bool IsSortedCore { get { return this.isSorted; } } /// <summary> /// ソートされたリストの並べ替え操作の方向を取得します。 /// </summary> protected override ListSortDirection SortDirectionCore { get { return this.sortDirection; } } /// <summary> /// ソートに利用する抽象化プロパティを取得します。 /// </summary> protected override PropertyDescriptor SortPropertyCore { get { return this.sortProperty; } } /// <summary> /// ApplySortCore で適用されたソートに関する情報を削除します。 /// </summary> protected override void RemoveSortCore() { this.sortDirection = ListSortDirection.Ascending; this.sortProperty = null; this.isSorted = false; } /// <summary> /// 指定されたプロパティおよび方向でソートを行います。 /// </summary> /// <param name="prop">抽象化プロパティ</param> /// <param name="direction">並べ替え操作の方向</param> protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction) { // ソートに使う情報を記録 this.sortProperty = prop; this.sortDirection = direction; // ソートを行うリストを取得 var list = Items as List<T>; if (list == null) { return; } // ソート処理 list.Sort(this.Compare); // ソート完了を記録 this.isSorted = true; // ListChanged イベントを発生させます this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); } /// <summary> /// 比較処理を行います。 /// </summary> /// <param name="lhs">左側の値</param> /// <param name="rhs">右側の値</param> /// <returns>比較結果</returns> private int Compare(T lhs, T rhs) { // 比較を行う var result = this.OnComparison(lhs, rhs); // 昇順の場合 そのまま、降順の場合 反転させる return (this.sortDirection == ListSortDirection.Ascending) ? result : -result; } /// <summary> /// 昇順として比較処理を行います。 /// </summary> /// <param name="lhs">左側の値</param> /// <param name="rhs">右側の値</param> /// <returns>比較結果</returns> private int OnComparison(T lhs, T rhs) { object lhsValue = (lhs == null) ? null : this.sortProperty.GetValue(lhs); object rhsValue = (rhs == null) ? null : this.sortProperty.GetValue(rhs); if (lhsValue == null) { return (rhsValue == null) ? 0 : -1; } if (rhsValue == null) { return 1; } if (lhsValue is IComparable) { return ((IComparable)lhsValue).CompareTo(rhsValue); } if (lhsValue.Equals(rhsValue)) { return 0; } return lhsValue.ToString().CompareTo(rhsValue.ToString()); } } }
フォームにはdataGridView1というDataGridViewが配置されている前提で、SortableBindingListの使用例を以下に記載する。
Form1.cs
public partial class Form1 : Form { public Form1() { this.InitializeComponent(); var list = new SortableBindingList<UserModel>() { new UserModel() { Id = "0010", FirstName = "Kurihara", LastName = "Yuki", Email = "yuki.kurihara@gmail.com", Password = "*****" }, new UserModel() { Id = "0020", FirstName = "Momotsuki", LastName = "Shinya", Email = "shinya.momotsuki@gmail.com", Password = "*****" } }; this.dataGridView1.DataSource = list; } }
ソートできない状態にする場合は、BindingSourceを挟んでDataGridView.DataSourceへリストを設定していたが、
SortableBindingListを利用する場合はそのままDataGridView.DataSourceへリストを設定できる。
これを実行すると、以下のようにカラムタイトルを選択してソートできるようになり、ソート方向を示す三角アイコンが表示されるようになる。