y-matsui::weblog

電子楽器、音楽、コンピュータ、プログラミング、雑感。面倒くさいオヤジの独り言

ViewStateとListBoxの怪

Multipleに設定したListBoxのpostback(ViewStateからの復元)でエライ目にあった。バグ潰しに丸々3日費やした。情けない。
具体的には、検索画面のインタフェースで、複数選択のListBoxの値を使ってクエリ文字列を生成し、同じ画面のデータグリッドに検索結果をバインド・・という当たり前の仕組み。しかし、ページング動作をさせた場合に、複数選択可能としたListBoxからのクエリ条件だけがおかしくなってしまう。ドロップダウンリストやチェックボックスラジオボタン、テキストボックスの場合は、全くおかしな動作をしない。
サンプルページを作って、複数選択できるようにしたListBoxの値を(当たり前なのだが)すべて取得することが出来る。postback動作で、選択が変更されるたびに他のコントロールへ値を渡すことが出来る。当たり前すぎる動作だ。
しかし、GridViewのページングが絡むとおかしな動作をしだすのである。ViewStateに埋め込まれた値が怪しいのかと思い、Request.Form("リストボックスの名前").ToString()で取り出してみても結果は同じ。

まず、GridViewのページングでは、Loadイベントが発生しない。
ListBoxの選択状態は、Loadが発生する場合には、上手く動作する。
ページングの動作で(恐らくViewStateからの復元)の場合には、先頭のひとつしか取り出せない。これはおかしい。selected=trueになっているはずのプロパティが、falseになっている。

もう、やけくそで、ListBoxの選択状態が変更された際に、自前の隠しフィールドに値を格納するようにして、ListBoxそのものではなく、自前隠しフィールドを参照するようにした。ページング動作でも、自前隠しフィールドの値は、変更されないのでお望みの動作をさせることができた。めでたしめでたし。

なんだか釈然としない解決策なのだが、ViewStateからの値復元で、ListBoxのプロパティなんかが欠落するというバグがあるらしいとの情報があるので、もしかしたら該当するのかもしれない。しかし、ListBoxアイテムのseletedなんていう情報を欠落させちゃまずいべ。