Googleみたいな検索フォームを作りたい
Googleみたいな検索フォームを作りたいと思った。検索クエリはQueryStringで引っ張ってきて、テキストボックスになにかを入力して検索ボタンをクリックすれば検索結果が更新されるようにしたいのだ。QueryStringでクエリを渡すようにすれば、他のページから検索クエリを投げることも簡単になるという寸法。
さてやってみよう。
DataGridViewとObjectDataSourceを配置して、ObjectDataSourceのSelectParameterをQueryStringから取ってくるようにする。TextBoxとButtonを配置して、Buttonのクリックイベントに
Response.Redirect("Search.aspx?query=" + TextBox1.Text);
などと書く。これだけでは、クエリがテキストボックスに表示されないので、Page_Loadに
TextBox1.Text = Request.QueryString["query"];
などと書いておいた。
ところが、これがうまくいかない。TextBoxのクエリがクリアされてしまって面白くない。この現象に、丸1日はまったのだが、デバッガで追ってみれば話は簡単だった。
Button1_Clickは、Page_Loadの後に呼ばれるのだった。Page_Loadが呼ばれた時点ではURLは変化していないため、その前にユーザーが入力したクエリがQueryString["query"]に入っている。ここでTextBox1.Textに代入しているのだから、クリアされてしまうというわけ。考えてみれば当たり前で、サーバサイドで処理している以上、Pageの初期化のほうが先に呼ばれるのは道理。
しかし、これでは最初に考えていた処理ができない。TextBox1のAutoPostbackプロパティなんかをいじりつつしばらく考えて、実は単純な話だったと気づいた。
Page_Loadに
if (TextBox1.Text.Length == 0) TextBox1.Text = Request.QueryString["query"];
と書く。ユーザーが検索語句を入力した後は、Page_Loadが呼ばれた時点ではPostBackが働いて、すでにText1.Textは復帰されている。なので、Lengthでチェックしてユーザーが入力していない場合だけQueryStringからクエリを取ってくれば良い。その後、Button1_Clickが呼ばれて、適切にRedirectされるという寸法。
めでたしめでたし。っつーか、こんな泥臭いこと世のASP.NETプログラマはみんなやってるんですかね。いちいちこんなん書くの嫌なんですけど。