お手上げ -> 解決
解決した。問題の原因は、イベントハンドラの多重登録だった。DataGridViewを使う際には
this.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler( delegate(object sender, DataGridViewEditingControlShowingEventArgs e) { e.Control.KeyPress += new KeyPressEventHandler(this.MyCellKeyPress); if (e.Control is TextBoxBase) { (e.Control as TextBoxBase).TextChanged += new EventHandler(this.MyCellTextChanged); } });
このように、KeyPressとTextChangedイベントハンドラを登録していたのだが、これだと当然ながらセルが編集モードに入る度にイベントハンドラが登録されてしまう。今となっては忘れたが、恐らくEditingControlShowingイベントの扱いを勘違いてしていたのだろう。
それにしても、このようにすることで、どうして前エントリのようにNullReferenceExceptionになるのかがさっぱりわからん。原因が判った所で、その理由が判らないと気持ちの悪いものだ。
問題の解決には、登録されたイベントハンドラは、不要になったら、つまりは編集用コントロールが消えたら、とっととアンワイヤしてやれば良いのだが、本当ならばあって欲しいEditingControlHidingイベントなんてものは無い。どうしたものか。
追記:
DataGridView.EditingControlは、編集モードの出入りでVisibleプロパティが反転しているのを確認できたので、とりあえずはVisibleChangedイベントでその他のイベントのワイヤ/アンワイヤをコントロールすることにしてみた。
this.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler( delegate(object sender, DataGridViewEditingControlShowingEventArgs e) { e.Control.VisibleChanged += new EventHandler( delegate(object innerSender, EventArgs innerArgs) { if (e.Control.Visible) { e.Control.KeyPress += new KeyPressEventHandler(this.MyKeyPress); if (e.Control is TextBoxBase) { (e.Control as TextBoxBase).TextChanged += new EventHandler(this.MyCellTextChanged); } } else { e.Control.KeyPress -= new KeyPressEventHandler(this.MyKeyPress); if (e.Control is TextBoxBase) { (e.Control as TextBoxBase).TextChanged -= new EventHandler(this.MyCellTextChanged); } } }); });
うーん、Visibleプロパティの反転を信じて良いものだろうか。心配になってきた。
また、このコードだけでは駄目だ。このままだと、今度はVisibleChangedイベントが重複してしまうので、こいつの多重登録を防ぐ手立てが必要。ここんところは辞書でイベントをワイヤしたコントロールを管理したり、と書き方はいろいろあると思うので省略する。
教訓:匿名デリゲートによるイベントの記述は、インプレイスに書けるので非常に重宝するのだが、イベントが多重登録される危険を忘れがちなので、注意が必要だ。