三回目。今回はソートしたときに DataGridView が無視してくれる問題についてです。といってもまあ自明の理なんですがね、
まず IBindingList の解説を少し引用しましょう。
ApplySort メソッドまたは RemoveSort メソッドを呼び出す場合は、Reset 列挙体を使用して ListChanged イベントを発生させてください。
ということでこれが原因です。このイベントを使わないと、DataGridView はデータソースにソートが適用されたタイミングを窺い知ることができません。
ではさくさく実装していきましょう。
bool IBindingList.SupportsChangeNotification { get { return true; } }
protected virtual void OnListChanged(ListChangedEventArgs e) {
if (this.listChanged != null)
this.listChanged(this, e);
}
void IBindingList.ApplySort(PropertyDescriptor property,
ListSortDirection direction) {
if (property == null) throw new ArgumentNullException("property");
TwoDimensionalArrayColumnDescriptor desc
= property as TwoDimensionalArrayColumnDescriptor;
if (desc == null) throw new ArgumentException("property");
if (!Enum.IsDefined(typeof(ListSortDirection), direction)) {
throw new InvalidEnumArgumentException("direction", (int)direction,
typeof(ListSortDirection));
}
ListComparer comparer = new ListComparer(desc.ColumnIndex, direction);
this.arrangedViews.Sort(comparer);
this.sortDirection = direction;
this.sortColumn = desc;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
void IBindingList.RemoveSort() {
this.arrangedViews.Clear();
this.arrangedViews.AddRange(this.rowViews);
this.sortDirection = ListSortDirection.Ascending;
this.sortColumn = null;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
SupportsChangeNotification プロパティが true を返すようにすることで、DataGridView は ListChanged イベントにイベントハンドラを登録しに来るようになります。
今回はこれだけ。でも通知系にはまだ問題があります。allowEdit を true にして、DataGridView でソート適用中のカラムの適当なセルを書き換えても自動で並び替えしてくれません。次はこれを考察します。