C#::ListBoxのオーナードロー(OwnerDrawVariable)時のサイズ再計算

System.Windows.Forms.ListBoxにはオーナードローの設定があって、それを使うと項目ごとに高さの違うリストとして表示できるようになる(DrawMode=DrawMode.OwnerDrawVariable)。つまり、長いカラムを折り返して表示したりできるようになるんだよ!!

だがしかし、その「項目を表示するために必要なサイズを求める」処理が各項目1度きりしか呼ばれない(アクティブな項目は表示するたびに呼ばれているようですが)ために、表示したあとウィンドウのサイズを変えると折り返した文字が見えなくなったり、逆に下にアホみたいな隙間が開いたりする。
これを再計算させる方法はないものか・・・とぐぐってみたら、どうやら一旦フレキシブルなオーナードローじゃなくしてから(DrawMode=DrawMode.OwnerDrawFixed)もう一度設定する(DrawMode=DrawMode.OwnerDrawVariable)といいらしい。で、これをResizeイベントに仕込めばいいんだけど、ListBoxのResizeイベントに仕込むと実行時に例外が出るようなので、親コンテナ(listBox.Parent)のResizeイベントに登録すればいいんだってさ。
でもこれやってみたらリサイズするたびに垂直スクロール位置が一番上まで戻っちゃうぜこんちくしょう!これを元の位置に戻す計算はめんどくさそうだな。保留でいいか。


しかしListBoxは便利だな。.NETの何がいいってListBoxとListViewがすごくいいよね。あとコントロールのDockとAnchor。C++でWM_SIZE引っ掛けて地道にもそもそ計算していたときとは雲泥の差だ。