如何在FormView的ItemUpdating事件中取得動態加入的控制項
MSDN論壇上的ASP.NET與AJAX版上有人提問【FormView搭配CheckBoxList做編輯】時,無法取得使用者所選擇的項目,問題應該是出在提問者是動態產生CheckBoxList,在Postback後沒有重新產生,以至於CheckBoxList的選項都是未選取的狀態。
【ASPX】
1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FVDemo.aspx.cs" Inherits="WebApplication1.FVDemo" %>
2:
3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4:
5: <html xmlns="http://www.w3.org/1999/xhtml">
6: <head runat="server">
7: <title></title>
8: </head>
9: <body>
10: <form id="form1" runat="server">
11: <div>
12: <asp:FormView ID="FormView1" runat="server" AllowPaging="True"
13: onpageindexchanging="FormView1_PageIndexChanging"
14: oniteminserting="FormView1_ItemInserting" ondatabound="FormView1_DataBound"
15: onitemupdating="FormView1_ItemUpdating">
16: <HeaderTemplate>
17: <table>
18: <tr>
19: <th>
20: RegionID
21: </th>
22: <td>
23: RegionDescription
24: </td>
25: </tr>
26: </HeaderTemplate>
27: <ItemTemplate>
28: <tr>
29: <th>
30: <asp:Label ID="Label1" runat="server" Text='<%# Eval("RegionID") %>'></asp:Label>
31: </th>
32: <td>
33: <asp:Label ID="Label2" runat="server" Text='<%# Eval("RegionDescription") %>'></asp:Label>
34: </td>
35: </tr>
36: <tr>
37: <td colspan="2">
38: <asp:Button ID="btnAdd" runat="server" onclick="btnAdd_Click" Text="Add" />
39: <asp:Button ID="btnEdit" runat="server" onclick="btnEdit_Click" Text="Edit" />
40: </td>
41: </tr>
42: </ItemTemplate>
43: <FooterTemplate>
44: </table>
45: </FooterTemplate>
46: <InsertItemTemplate>
47: <tr>
48: <th>
49: <asp:CheckBoxList ID="cbl" runat="server"
50: RepeatDirection="Horizontal">
51: </asp:CheckBoxList>
52: <asp:TextBox ID="txtRegionID" runat="server"></asp:TextBox>
53: </th>
54: <td>
55: <asp:TextBox ID="txtRegionDescription" runat="server"></asp:TextBox>
56: </td>
57: </tr>
58: <tr>
59: <td colspan="2">
60: <asp:Button ID="btnInsert" runat="server" Text="Insert" CommandName="Insert" />
61: <asp:Button ID="btnCancel" runat="server" Text="Cancel" onclick="btnCancel_Click" />
62: </td>
63: </tr>
64: </InsertItemTemplate>
65: <EditItemTemplate>
66: <tr>
67: <th>
68: <asp:Panel ID="Panel1" runat="server">
69: </asp:Panel>
70: <asp:TextBox ID="txtRegionID" Text='<%# Bind("RegionID") %>' runat="server"></asp:TextBox>
71: </th>
72: <td>
73: <asp:TextBox ID="txtRegionDescription" Text='<%# Bind("RegionDescription") %>' runat="server"></asp:TextBox>
74: </td>
75: </tr>
76: <tr>
77: <td colspan="2">
78: <asp:Button ID="btnInsert" runat="server" Text="Update" CommandName="Update" />
79: <asp:Button ID="btnCancel" runat="server" Text="Cancel" onclick="btnCancel_Click" />
80: </td>
81: </tr>
82: </EditItemTemplate>
83: </asp:FormView>
84: <br />
85: </div>
86: </form>
87: </body>
88: </html>
【CS】
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Web;
5: using System.Web.UI;
6: using System.Web.UI.WebControls;
7:
8: namespace WebApplication1
9: {
10: public partial class FVDemo : System.Web.UI.Page
11: {
12: protected void Page_Load(object sender, EventArgs e)
13: {
14: if (!IsPostBack)
15: FormViewDataBind();
16: else
17: if (FormView1.CurrentMode == FormViewMode.Edit) GenCheckBox();
18: }
19:
20: private void FormViewDataBind()
21: {
22: using (NorthwindEntities context = new NorthwindEntities())
23: {
24: FormView1.DataSource = from p in context.Regions
25: select p;
26: FormView1.DataBind();
27: }
28: }
29:
30: protected void FormView1_PageIndexChanging(object sender, FormViewPageEventArgs e)
31: {
32: FormView1.PageIndex = e.NewPageIndex;
33: FormViewDataBind();
34: }
35:
36: protected void btnEdit_Click(object sender, EventArgs e)
37: {
38: FormView1.ChangeMode(FormViewMode.Edit);
39: FormViewDataBind();
40: }
41:
42: protected void btnAdd_Click(object sender, EventArgs e)
43: {
44: FormView1.ChangeMode(FormViewMode.Insert);
45: }
46:
47: protected void btnCancel_Click(object sender, EventArgs e)
48: {
49: FormView1.ChangeMode(FormViewMode.ReadOnly);
50: }
51:
52: protected void FormView1_ItemInserting(object sender, FormViewInsertEventArgs e)
53: {
54: TextBox txtRegionID = FormView1.FindControl("txtRegionID") as TextBox;
55: TextBox txtRegionDescription = FormView1.FindControl("txtRegionDescription") as TextBox;
56: CheckBoxList cbl = FormView1.FindControl("cbl") as CheckBoxList;
57: string strList = string.Empty;
58: foreach (ListItem item in cbl.Items)
59: {
60: if (!item.Selected) continue;
61: strList += item.Value;
62: }
63: Response.Write(string.Format("RegionId = {0}, RegionDescription = {1}, List = {2}<br/>", txtRegionID.Text, txtRegionDescription.Text, strList));
64: }
65:
66: protected void FormView1_DataBound(object sender, EventArgs e)
67: {
68: GenCheckBox();
69: }
70:
71: private void GenCheckBox()
72: {
73: Panel pan1 = FormView1.FindControl("Panel1") as Panel;
74: if (pan1 != null)
75: {
76: CheckBoxList cbl = new CheckBoxList();
77: cbl.ID = "cbl";
78: for (int i = 0; i < 5; i++)
79: {
80: ListItem li = new ListItem();
81: li.Text = "Q" + i.ToString();
82: li.Value = li.Text;
83: cbl.Items.Add(li);
84: }
85: pan1.Controls.Add(cbl);
86: }
87: }
88:
89: protected void FormView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
90: {
91: TextBox txtRegionID = FormView1.FindControl("txtRegionID") as TextBox;
92: TextBox txtRegionDescription = FormView1.FindControl("txtRegionDescription") as TextBox;
93: CheckBoxList cbl = FormView1.FindControl("cbl") as CheckBoxList;
94: string strList = string.Empty;
95: foreach (ListItem item in cbl.Items)
96: {
97: if (!item.Selected) continue;
98: strList += item.Value;
99: }
100: Response.Write(string.Format("RegionId = {0}, RegionDescription = {1}, List = {2}<br/>", txtRegionID.Text, txtRegionDescription.Text, strList));
101: }
102: }
103: }
【流程說明】下圖左為ReadOnly模式的執行結果,當使用者按下編輯後,切換至下圖中的Edit模式,當使用者按下Update按鈕時,希望取得使用者於CheckBoxList所選取的項目(下圖右)。
【作法說明】
- 當使用者於上圖左按下Edit按鈕時,觸發btnEdit_Click事件,並於事件中以FormView.ChangeMode方法切換至Edit模式,並呼叫FormView的DataBind事件才能真正切換模式,DataBind動作不得省略。
- 由於上一步驟執行FormView.DataBind,因此會觸發FormView的DataBound事件,在此呼叫GenCheckBox方法以動態產生CheckBoxList及其Items。
- 當使用者按下Update按鈕時,首先會觸發Page_Load事件,由於CheckBoxList是動態產生的,因此必須重新建立,所以筆者在Page_Load事件中再次呼叫GenCheckBox來產生CheckBoxList。
- 由於Update按鈕的CommandName設定為Update,因此Click時會觸發ItemUpdating事件,此時便能順利取得使用者於動態產生的CheckBoxList中所選擇的項目。
參考資料: