仕事の都合で未だDataGridを手放せず…
セルの背景色を変えたいってんで、DataGridColumnStyleの派生クラスを作った。
用途は読み取り専用文字列とチェックボックスができればいいんで、前者はDataGridColumnStyleから直接派生、後者はDataGridBoolColumnから派生させた。
ところが、どういうわけか後者のPaintの中で基底クラスのPaintを呼び出しても、そのセルが選択されている場合、backBrush引数に渡したブラシではなく、デフォルトの色が使われてしまうことが判明。
これじゃ使えねぇんで、チェックボックスもDataGridColumnStyleから直接派生させることにする。
で、内部でCheckBoxコントロールをホストするようにしてみた…ら失敗。
DataGridColumnStyleは1列につき1つしかないが、CheckBoxはセルの数だけ必要になる。CheckBoxを使うにはPaintイベントの中で生成するしかないが、再描画の度にnewするなんて馬鹿げてるので却下。
仕方が無いのでControlPaintでゴリゴリ描くことにする…が、またも詰まる。
セルの値が変更される時はDataGridColumnStyle.ColumnStartedEditingを呼び出すべきなのだが、こいつの引数はControl。しかし今回はCheckBoxをホストせずに自力で描くのでControlがない。
同じようにCheckBoxをホストせずに自力描画しているDataGridBoolColumnはどうしているのかと思ったら、DataGrid.ColumnStartedEditing(Rectangle)を直接呼び出してやがる。
真似しようと思ったら、こいつのアクセス権はprotected internal。DataGridBoolColumnはDataGridと同じアセンブリ内にあるからいいが、俺の作ろうとしているクラスからは呼び出せない。
一応protectedはついてるので、DataGridの派生クラスからなら呼び出せるから、そいつ経由で中継してやればいいのだが、そうすると俺の作りたいカスタムColumnStyleは、そのDataGrid派生クラスと一緒にしか使えなくなってしまう。
Reflectorで見てみたら、DataGrid.ColumnStartedEditing(Control)は、Control.Boundsを渡してDataGrid.ColumnStartedEditing(Rectangle)を呼び出しているだけで、必要なのはBoundsの情報だけなので、DataGridColumnStyle.ColumnStartedEditing(Control)にダミーのControlを渡して切りぬけることにする。
DataGridColumnStyleってのは、Controlをホストしない派生クラスを想定していないらしい。
以前にもどこかでこういうことがあった気がするが、internalってのは卑怯なアクセス権である。
クラスに使うなら問題ないのだが、メンバに使うのはよろしくない。
そのメンバを呼び出すクラスのアセンブリ外部にある派生クラスからは呼び出せないからである。
もうダメ!メソッドにinternal使うの禁止!
派生できる作りになっているくせに、派生クラスのことを考えていない奴が多すぎる!