更新時に検証を行う
次に、更新時にデータの未入力チェック(RequiredFieldValidator)や入力形式のチェック(RegularExpressionValidator)を行う方法を考えます。これもTemplateFieldが使えればデザイン画面から設定するだけで済むのですが、そうはいかないのでプログラム中でコントロールを生成し、設定する必要があります。ここでもTraceモードを利用してどこにコントロールを追加するかを考慮し、プログラムを記述していきます。また、検証コントロールはデータ行が編集モードの場合だけ追加すればよいものなので、先ほど追加した条件文をうまく利用していきましょう。
ここで実際に記述したプログラムは次のようになりました。
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) if (e.Row.RowIndex != GridView1.EditIndex) ((LinkButton)e.Row.Cells[0].Controls[2]).OnClientClick = "return confirm('削除してよろしいですか');"; else { // RequiredFieldValidator の追加 TableCell rfvTargetCell = e.Row.Cells[2]; RequiredFieldValidator rfv = new RequiredFieldValidator(); rfv.ErrorMessage = "必須"; rfv.Display = ValidatorDisplay.Dynamic; string textbox1ClinentID = rfvTargetCell.Controls[0].ClientID; string[] textbox1IDarray = textbox1ClinentID.Split('_'); rfv.ControlToValidate = textbox1IDarray[textbox1IDarray.Length - 1]; rfvTargetCell.Controls.Add(rfv); // RegularExpressionValidator の追加 TableCell revTargetCell = e.Row.Cells[3]; RegularExpressionValidator rev = new RegularExpressionValidator(); rev.ErrorMessage = "正しいメールアドレスを入力してください"; rev.ValidationExpression = @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"; rev.Display = ValidatorDisplay.Dynamic; string textbox2ClinentID = revTargetCell.Controls[0].ClientID; string[] textbox2IDarray = textbox2ClinentID.Split('_'); rev.ControlToValidate = textbox2IDarray[textbox2IDarray.Length - 1]; revTargetCell.Controls.Add(rev); } }
このプログラムで奇妙に見える点は、検証コントロールの対象となるコントロールのIDを取り出している部分です。
ターゲットとなるセル(rfvTargetCellおよびrevTargetCell)の最初のコントロール(Controls[0])がそれぞれ検証コントロールの対象となるので、本来であればこのコントロールのIDプロパティの値をControlToValidateプロパティに設定すればよいはずです。しかし、そのようなプログラムを記述して実行してみると、なぜか実行中にコントロールのIDの値を取り出すことができません。IDの代わりにClientIDを利用すると、値は取り出せるのですが、その値はページ内のコントロールの階層関係を含んだ値になっています。検証コントロールのControlToValidateプロパティに設定する値にはこの階層関係を含むことができないため、上記のプログラムではコントロールのClientIDを「_」で分割し、その最後の値を取り出してControlToValidateプロパティに設定しています。
このようにプログラムを記述することによって、userName項目に対して必須チェックが、またmail項目に対して入力形式のチェックが行われるようになります。
プログラミングによる対応の限界
ここまでの記述で、EnableSortingAndPagingCallbacksプロパティという名前なのに、ソートについての説明がないことに気づいた方もいるかもしれません。実はソートが有効になっている場合、GridViewの行を編集モードにしたままデータの並び替えが行われてしまいます。そしてそのとき、編集モードの行に検証コントロールを追加することはできないのです。このため、GridViewを利用してページを読み込み直すことなく、ページングとデータのソートの両方を行いたい場合には、GridViewからのデータの更新は利用できないことになります。
まとめ
制限の多いEnableSortingAndPagingCallbacksプロパティですが、だからといってまったく利用できないわけではありません。制限を理解したうえで、どこまで工夫すれば実際に使えるかを考えてみるのも面白いと思います。
このように現在のコントロールの制限を回避する方法を調べていくときには、必ずASP.NETがどのように動作しているかを調査し、それを理解する必要が出てきます。このような問題に取り組む中で理解したことは、間違いなく身についた知識となって別のところでも応用が利くでしょう。
だからといって納期がせまっている中でこのような問題に取り組むのはやめてくださいね。

