実装
RadioButtonコントロールから派生したコントロールを作成します。

このコントロールでは、コントロールの描画とポストバック時の値の取得の2ヶ所を変更する必要があります。
コントロールの描画
Renderメソッドのシグネチャは下記のようになっています。
protected virtual void Render(HtmlTextWriter writer)
今回の実装は、Render時に新たなHtmlTextWriterオブジェクトを作成して、そこでname属性およびvalue属性の変換を行うこととします。
HtmlTextWriterオブジェクトの挙動を調べると、RadioButtonコントロールが属性を追加する際には、AddAttributeメソッドを呼んでいます。これを、下記のように変更します。
public override void AddAttribute(HtmlTextWriterAttribute key, string value) { switch (key) { case HtmlTextWriterAttribute.Name: base.AddAttribute(key, control.GroupName); break; case HtmlTextWriterAttribute.Value: base.AddAttribute(key, control.UniqueID); break; default: base.AddAttribute(key, value); break; } }
name属性を設定する際には、key引数にHtmlTextWriterAttribute.Nameが渡されます。このときには、コントロールのGroupNameプロパティの値をそのまま設定することにします。
また、value属性を設定する際には、key引数にHtmlTextWriterAttribute.Valueが渡されます。このときには、コントロールのIDに接頭辞をつけたものを渡せばよいのですが、UniqueIDプロパティがこの目的に使用できます。
この結果、生成されるHTMLは下記のようになります。期待した通りの出力になっていることが確認できます。
<tr> <td> <input id="GridView1_ctl02_RadioButton1" type="radio" name="Radio" value="GridView1$ctl02$RadioButton1" /> </td><td>First</td><td>First Item</td> </tr> <tr> <td> <input id="GridView1_ctl03_RadioButton1" type="radio" name="Radio" value="GridView1$ctl03$RadioButton1" /> </td><td>Second</td><td>Second Item</td> </tr> <tr> <td> <input id="GridView1_ctl04_RadioButton1" type="radio" name="Radio" value="GridView1$ctl04$RadioButton1" checked="checked" /> </td><td>Third</td><td>Selected Item</td> </tr> <tr> <td> <input id="GridView1_ctl05_RadioButton1" type="radio" name="Radio" value="GridView1$ctl05$RadioButton1" /> </td><td>Fourth</td><td>Fourth Item</td> </tr> <tr> <td> <input id="GridView1_ctl06_RadioButton1" type="radio" name="Radio" value="GridView1$ctl06$RadioButton1" /> </td><td>Fifth</td><td>Fifth Item</td> </tr>
Postback時の結果取得
前節のコードによって描画は行えましたので、後はPostback時に選択結果の反映をする必要があります。これは、LoadPostDataメソッドをオーバーライドすることによって行うことができます。
protected override bool LoadPostData( string postDataKey, NameValueCollection postCollection) { bool newChecked = postCollection[GroupName] == this.UniqueID; if (this.Checked != newChecked) { this.Checked = newChecked; return newChecked; } return false; }
LoadPostDataメソッドでPOSTデータから値を読み込んでコントロールの状態を復元します。また、コントロールの状態が変わったらtrueを返します。
今回は、描画時にname属性にGroupNameを、value属性にUniqueIDを設定しているため、Postパラメータから読み込む際にもGroupNameキーの値がUniqueIDと等しいかどうかによって選択されたかどうかを確認しています。
ただし、RadioButtonのときは、新たに選択されたときのみtrueを返す(非選択になった時にはfalseを返す)ようなので、今回もそのようにしています。
これで、コントロールが完成しました。後は、通常通りこのコントロールを貼り付ければ、データバインドコントロール内でも単一選択を行うことができるようになります。
最後に
本稿ではASP.NETで提供されていない、データ バインド コントロールの項目をまたがって使用できるラジオボタンを示しました。
ASP.NETでは、必要な機能がない場合でも、比較的容易にコントロールを作成することが可能です。
