ASPを解決する.NET GridViewにRadioButtonを入れると単一選択できません


今日の開発で出会った問題は、GridViewにRadioButtonを含むテンプレート列を追加すると、結果が実行されるということです...ああ、ラジオボタンはもっと選べます!囧啊!今日のエラーを示すために、私はやはり機能シーンをシミュレートしましょう.私が実現する機能は、ラジオボタンを含む学生情報のリストを表示し、行を選択して詳細を表示することです.
          1.問題の表示
①まずGridViewを用意し、学生の基本情報と最も重要なラジオボタンを表示します.コードは以下の通りです.
   
   
   
   
  1. <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"> 
  2.         <Columns> 
  3.         <asp:TemplateField> 
  4.           <ItemTemplate> 
  5.           <asp:RadioButton ID="rbStudent" runat="server" /> 
  6.           ItemTemplate> 
  7.         asp:TemplateField> 
  8.  
  9.         <asp:BoundField DataField="SName" HeaderText=" "  /> 
  10.         <asp:BoundField DataField="SSex" HeaderText=" " /> 
  11.         Columns> 
  12.         asp:GridView> 

②次に、データをバインドするエンティティを準備します.コードは次のとおりです.
   
   
   
   
  1. public class Student  
  2.   {  
  3.       public string SID { getset; }  
  4.       public string SName { getset; }  
  5.       public string SSex { getset; }  
  6.   } 

③データを初期化し、GridViewリストをバインドします.コードは以下の通りです.
   
   
   
   
  1. protected void Page_Load(object sender, EventArgs e)  
  2.        {  
  3.            if (!IsPostBack)  
  4.            {  
  5.                this.BindGridView();  
  6.            }  
  7.        }  
  8.  
  9.        public void BindGridView()  
  10.        {  
  11.            List sList = new List()  
  12.            {  
  13.                new Student(){ SID = "s001", SName=" ", SSex=" "},  
  14.                new Student(){ SID = "s002", SName=" ", SSex=" "},  
  15.                new Student(){ SID = "s003", SName=" ", SSex=" "}  
  16.            };  
  17.  
  18.            GridView1.DataSource = sList;  
  19.            GridView1.DataBind();  
  20.        }  

この時は何の問題もないように見えますが、実行すると、ラジオボックスが自分の役割を失っていることに気づきました.
        
何が原因ですか.注意深い人はRadioButtonがGroupName属性を設定していないのでグループに属していないと言うかもしれませんが、実は私がこの属性を設定した後も無効です!
          2.解決策
①問題分析
実行後、ソースコードを右クリックするとこの奇妙な問題が発見されました.GridViewはinputのname属性に自動的に値を付与し、各行のname属性が異なるため、単一選択できない問題が発生しました.GridViewは次のように世代コードを生成します.
   
   
   
   
  1. <table cellspacing="0" rules="all" border="1" id="GridView1" style="border-collapse:collapse;"> 
  2.         <tr> 
  3.             <th scope="col"> th><th scope="col"> th><th scope="col"> th> 
  4.         tr><tr> 
  5.             <td> 
  6.           <input id="GridView1_rbStudent_0" type="radio" name="GridView1$ctl02$rbStudent" value="rbStudent" /> 
  7.           td><td> td><td> td> 
  8.         tr><tr> 
  9.             <td> 
  10.           <input id="GridView1_rbStudent_1" type="radio" name="GridView1$ctl03$rbStudent" value="rbStudent" /> 
  11.           td><td> td><td> td> 
  12.         tr><tr> 
  13.             <td> 
  14.           <input id="GridView1_rbStudent_2" type="radio" name="GridView1$ctl04$rbStudent" value="rbStudent" /> 
  15.           td><td> td><td> td> 
  16.         tr> 
  17.     table> 

各RadioButtonコントロールのname属性が異なり、単一選択できない問題が発生していることがわかりますが、この元凶をどう解決すればいいのでしょうか.
私が最初に考えた方法は、name属性を人工的に統一することです.では、どのように変更しますか?それは簡単だと言う人もいるかもしれませんが、GridViewのOnRowDataBoundイベントを使って行をバインドするときにRadioButtonのname属性を変えればいいのです!コードは次のとおりです.
   
   
   
   
  1. protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)  
  2.        {  
  3.            if (e.Row.RowType == DataControlRowType.DataRow)  
  4.            {  
  5.                RadioButton RadioButtionRB = (RadioButton)e.Row.FindControl("rbStudent");  
  6.                RadioButtionRB.Attributes["name"] = "student";  
  7.            }  
  8.        }  

しかし、運行後、私はまた失望しました.何が原因ですか?RadioButtonがクライアントから出力されたときに外にマークが付いていて、name属性がSPANに追加されたので、囧死しました.証拠は以下の通りである.
    
    
    
    
  1. <span name="student"><input id="GridView1_rbStudent_0" type="radio" name="GridView1$ctl02$rbStudent" value="rbStudent" />span> 
  2.           td><td> td><td> td> 
  3.         tr><tr> 
  4.             <td> 
  5.           <span name="student"><input id="GridView1_rbStudent_1" type="radio" name="GridView1$ctl03$rbStudent" value="rbStudent" />span> 
  6.           td><td> td><td> td> 
  7.         tr><tr> 
  8.             <td> 
  9.           <span name="student"><input id="GridView1_rbStudent_2" type="radio" name="GridView1$ctl04$rbStudent" value="rbStudent" />span> 
  10.           td><td> td><td> td> 

この考え方は通用しないようですね.JSしか使えないので、本題が来ました.データバインド後、JSでGridViewのRadioButtonを遍歴してname属性を同じ値に変更することにしました.通じますか.やってみよう!          
②問題解決
まず、GridView内のRadioButtonを巡回し、名前属性を「myradio」などの統一値に設定するJS関数を実装します.コードは次のとおりです.
   
   
   
   
  1. <span class="string">"text/javascript"</span><span>>  </span></span></li> <li><span>       </span><span class="keyword">function</span><span> SetRadioName() {  </span></li> <li class="alt"><span>           </span><span class="keyword">var</span><span> gv = document.getElementById(</span><span class="string">"GridView1"</span><span>); </span><span class="comment">// GridView ID </span><span> </span></li> <li><span>           </span><span class="keyword">var</span><span> myradio = gv.getElementsByTagName(</span><span class="string">"input"</span><span>); </span><span class="comment">// GridView Inputhtml </span><span> </span></li> <li class="alt"><span>           </span><span class="keyword">for</span><span> (</span><span class="keyword">var</span><span> i = 0; i < myradio.length; i++) {  </span></li> <li><span>               </span><span class="keyword">if</span><span> (myradio[i].type == </span><span class="string">'radio'</span><span>)</span><span class="comment">//hidden </span><span> </span></li> <li class="alt"><span>               {  </span></li> <li><span>                   myradio[i].setAttribute(</span><span class="string">"name"</span><span>, </span><span class="string">"myradio"</span><span>);  </span></li> <li class="alt"><span>               }  </span></li> <li><span>           }  </span></li> <li class="alt"><span>       }  </span></li> <li><span>     

次に、データのバインド後に呼び出したスクリプトを登録するか、ページラベルビューの一番下にスクリプトを書きます.コードは次のとおりです.
    
    
    
    
  1. protected void Page_Load(object sender, EventArgs e)  
  2.        {  
  3.            if (!IsPostBack)  
  4.            {  
  5.                this.BindGridView();  
  6.                ScriptManager.RegisterStartupScript(thisthis.GetType(), Guid.NewGuid().ToString(),  
  7.                    "SetRadioName()"true);  
  8.            }  
  9.        }  

実行、成功!!!完璧に解決!