Gridview搭配單選的RadioButton,並且保留用戶的選項
在撰寫ASP.NET網頁程式時,其實最讓我覺得很多樣化的一個元件,就是GridView這類型的控件,
它支援ItemTemplate的定義,讓其他ASP.NET控件或是指定的HTML Tag可以直接使用於GridView之中。
為了讓GridView有更多特定需求的使用時,通常也更會用到GridView中的幾個重要的Events:
RowDataBound()、RowCreated()、DataBound()或是RowCommand()、PreRender()。這些Events的應用可以
參考<GridView Class>上的說明。
至於這一篇的內容,主要是因為被詢問到如何讓GridView結合RadioButton達到單選的功能,並且在網頁
PostBack或是GridView選擇分頁時,可以記錄目前用戶所選擇的項目。等到回到目前該頁面時,仍然可以
將選擇的項目還原於畫面中。
對於GridView結合ASP.NET控件中的RadioButton,無法達成RadioButton單選的問題。我想網路上非常多資
料可以查詢,在這裡我就不多加描述,因為本範例也會使用<GridView 資料列單選功能 - ASP.Net魔法學院>
的方法來完成單選的功能。
然而,由於大部分搜尋出來的結果都是介紹透過ViewState保存GridView選擇的內容,但是針對使用RadioButton支
援單選又要能保存的內容就沒有看到。也許是我找的不夠仔細。
因此,我透過上述參考的單選方法,再撰寫配合JavaScript與Session就可以完成保留住用戶選項的功能。
〉實作概念:
針對實作的概念,主要透過下方二個情境來說明,如何結合JavaScript與Session即可保留住用戶選項,並且不會隨著
畫面PostBack之後遺失掉剛才選擇的項目。
在情境1:主要透過後端程式,將用戶在畫面中選擇的RadioButton對應的Value擷取出來,儲存於Session中。這樣的作法,
可以隨著用戶每次選擇的結果,進行轉換Session中的內容,永遠保留最新的值。
然而,Response的結果,則是分頁後的內容,代表畫面中的GridView所有RadioButton目前是沒有一個被選取的。
情境2:主要是當網頁由情境1完成Response後的畫面(假設沒有選擇任何RadioButton),再選擇回到上一個畫面(具有選擇
RadioButton的畫面)時,後端程式會先判斷目前送出的Request中是否有被選擇的RowSelected,由於是從沒有選擇任何項
目的畫面往上一個畫面,所以會取得null;因此,後端程式會擷取出Session中暫存的值,並且組合JavaScript字串(字串內
容為:繪製RadioButton選項被選取的JavaScript方法字串)。最後隨著Response附加到畫面的最下方。讓HTML DOM在執行
時,即可以繪製畫面中的選項。
〉實作範例:
(1) 建立一個GridView,並且透過<asp:TemplateField />加入RadioButton元件;並且透過Eval取得DataBind後的欄位。
1: //建立自動分頁功能與實作PageIndexChanging事件
2: //透過<input type="radio" />來取代ASP.NET中的RadioButton控件無法支援單選的問題
3: <asp:GridView ID="GridView1" runat="server" AllowPaging="True"
4: onpageindexchanging="GridView1_PageIndexChanging" >
5: <Columns>
6: <asp:TemplateField HeaderText="選擇" InsertVisible="False">
7: <ItemTemplate>
8: <input id="Radio" type="radio" id='<%# Eval("ProductID") %>' name="RowSelected" value='<%# Eval("ProductID") %>' />
9: </ItemTemplate>
10: </asp:TemplateField>
11: </Columns>
12: </asp:GridView>
(2) 撰寫一個JavaScript方法,專門處理畫面中GridView欄位中那一個<input type="radio" />需要被選取;
1: <script type="text/javascript">
2: //注意form1:是使用目前頁面中的form名稱;隨實作的form不同要進行更換;
3: //注意RowSelected:是<input type="radio" name="RowSelected" />中的name名稱,要記得統一。
4: function FindRadioButton(pValue) {
5: for (var x = 0; x < document.form1["RowSelected"].length; x++) {
6: if (document.form1.RowSelected[x].value == pValue) {
7: document.form1.RowSelected[x].checked = true;
8: break;
9: }
10: }
11: }
12: </script>
(3) 後端.cs程式端需要處理的任務:擷取Request.Form中被選擇的Radio項目、將它儲存至Session中,最後,
由後端組合要執行上述用於判斷那一筆資料的<input type="radio" />要被選擇的javascript到畫面中。
1: //宣告一個公用變數,記錄目前被選擇項目的ID。
2: private string gSelectedID = string.Empty;
3:
4: protected void Page_Load(object sender, EventArgs e)
5: {
6: if (!IsPostBack)
7: {
8: //匯入GridView的資料內容
9: FeedData();
10: }
11: else
12: {
13: //取得Request.Form中名為"RowSelected"的屬性值(value)
14: string tID = Request.Form["RowSelected"];
15: //如果是null代表目前的Request.Form中沒有名為RowSelected的控件
16: if (tID != null)
17: {
18: Session.Add("RowSelected", tID);
19: }
20: else
21: {
22: //使用由後端程式組合JavaScript的方法,讓Page在Response之後,直接執行指定的JavaScript方法。
23: if (Session["RowSelected"] != null)
24: {
25: gSelectedID = Session["RowSelected"].ToString();
26: Literal1.Text = "<script>FindRadioButton(" + gSelectedID + ");</script>";
27: }
28: }
29: }
30: }
看完上述說明的實作概念,不知道是否覺得是個很簡單的作法呢?!不管如何,其實在撰寫ASP.NET的程式時,
對於Page的Life Cycle與HTTP Reuqest/Response很清楚的話,我認為該篇的方法會讓你覺得非常有心得,因為裡面
製作的部分,運用了上述二個重要概念的精神。分享上述的方法,希望有所幫助。
References:
‧GridView 資料列單選功能 - ASP.Net魔法學院 (使用原理,建議閱讀)
‧ASP.NET Page Life Cycle Overview (必讀)
‧Data Binding Events for Data-Bound Controls (針對GridView/TreeView/FormView等,可使用Data Binding方法的元件都要看)