Out of Memory

本ブログは更新を停止しました。Aerieをよろしくお願いいたします。

目次

Blog 利用状況

ニュース

2009年3月31日
更新を停止しました。引き続きAerieを御愛顧くださいませ。
2009年2月3日
原則としてコメント受付を停止しました。コメントはAerieまでお願いいたします。
詳細は2月3日のエントリをご覧ください。
2008年7月1日
Microsoft MVP for Developer Tools - Visual C++ を再受賞しました。
2008年2月某日
MVPアワードがVisual C++に変更になりました。
2007年10月23日
blogタイトルを変更しました。
2007年7月1日
Microsoft MVP for Windows - SDKを受賞しました!
2007年6月20日
スキル「ニュース欄ハック」を覚えた!
2006年12月14日
記念すべき初エントリ
2006年12月3日
わんくま同盟に加盟しました。

カレンダー

中の人

αετο? / aetos / あえとす

シャノン? 誰それ。

顔写真

埼玉を馬鹿にする奴は俺が許さん。

基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。

書庫

日記カテゴリ

internal<s>には気をつけろ</s>禁止!

仕事の都合で未だ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使うの禁止!
派生できる作りになっているくせに、派生クラスのことを考えていない奴が多すぎる!

投稿日時 : 2007年2月14日 13:24

Feedback

# re: internalには気をつけろ 2007/02/14 14:46 シャノン

続・調査報告。
ダメだ。徹底的に腐ってる。

自前でチェックボックスを描画するにあたり、マウスクリックとキーダウンを検出しなければならない。
お手本にしているDataGridBoolColumnがどうやっているかというと、クリックされた時にはOnMouseDown、キーが押された時にはOnKeyDownというメソッドが呼ばれているらしい。
こいつらはDataGridColumnStyleの同名メソッドをオーバーライドしている。で、アクセス権がいやらしいことに internal virtualになっている。
クラス自体は継承可能になっているくせに、このメソッドは、自分のアセンブリ内にあるクラスにしかオーバーライドさせないというケチな作り。
DataGridColumnStyle.OnKeyDownは、どういうわけか内部でEnterNullValueを呼び出している。オーバーライドできないのでこれを阻止する方法はなく、どうやっても値がクリアされてしまう(DataGrid.ProcessDialogKeyをオーバーライドして、基底クラスに呼ばせなければいいのだが、それではデフォルトの動きが再現できない)。

タイトル
名前
Url
コメント