DataGridView にカスタムクラスをバインドし、列ヘッダーをクリックしたときにソートする方法。
データベースから取得した DataTable をバインドするときは、(設定すれば)自動でやってくれるが、オブジェクトデータソースを使うときは、いろいろと用意が必要。
カスタムクラスと、カスタムクラスのコレクションを用意する
コレクションは、シリアル化する必要がないなら、ジェネリックを使える。
class Hoge {
適切に実装
}
class HogeCollection : List<Hoge> {
実装不要
}
カスタムクラスの比較クラスを用意する
System.Collection.Generics.Comparer クラス を継承した、比較クラスを用意する。
class HogeComparer : System.Collections.Generic.Comparer {
private string _比較対象プロパティ = 適切に初期化;
private bool _Ascending = true;
///
/// 比較の対象とするプロパティの名称を取得、または設定します。
///
public string 比較対象 {
get { return this.property; }
set {
// 対象のプロパティが登録されているか、確認する
Type chargeType = typeof(Hoge);
System.Reflection.PropertyInfo[] info = chargeType.GetProperties();
for (int idx = 0; idx < info.Length; idx++) {
string propertyName = info[idx].Name;
if (propertyName.CompareTo(value) == 0) {
this.property = value;
return;
}
}
throw new ArgumentException("間違ってるよ");
}
}
public override int Compare(Hoge x, Hoge y) {
System.Reflection.PropertyInfo xInfo = x.GetType().GetProperty(this.property);
System.Reflection.PropertyInfo yInfo = y.GetType().GetProperty(this.property);
if (xInfo == null || yInfo == null) {
return (xInfo == null ? 1 : 0) - (yInfo == null ? 1 : 0);
}
object xObj = xInfo.GetValue(x, null);
object yObj = yInfo.GetValue(y, null);
IComparable comp = xObj as IComparable;
if (comp != null) {
return comp.CompareTo(yObj) * (this._Ascending == true ? 1 : -1);
} else {
// 比較できない
return 0;
}
}
}
UIの設定
BindingSource, DataGridView を用意し、適切に設定する。
DataGridView.ColumnHeaderMouseClick イベント をハンドルする。
private DataGridViewColumn lastSortedColumn = null;
private void dataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
HogeCollection list = HogeBindingSource.DataSource as HogeCollection;
if (list == null) { return; }
DataGridViewColumn column = this.dataGridView.Columns[e.ColumnIndex];
DataGridViewHeaderCell header = column.HeaderCell;
bool asc = true;
if (lastSortedColumn != null) {
if (lastSortedColumn == column) {
direction = (lastSortedColumn.HeaderCell.SortGlyphDirection == SortOrder.Ascending ? false : true);
}
lastSortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
}
HogeComparer comparer = new HogeComparer();
comparer.比較対象 = column.DataPropertyName;
comparer.SortOrder = direction;
this.dataGridView.EndEdit(); // 編集を強制終了
list.Sort(comparer);
lastSortedColumn = column;
lastSortedColumn.HeaderCell.SortGlyphDirection = (direction ? SortOrder.Ascending : SortOrder.Descending);
this.dataGridView.Refresh(); // 必要
}
投稿日時 : 2005年10月31日 21:02