如何在FormView的ItemUpdating事件中取得動態加入的控制項

如何在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所選取的項目(下圖右)。

imageimageimage

 

【作法說明】

  1. 當使用者於上圖左按下Edit按鈕時,觸發btnEdit_Click事件,並於事件中以FormView.ChangeMode方法切換至Edit模式,並呼叫FormView的DataBind事件才能真正切換模式,DataBind動作不得省略。
  2. 由於上一步驟執行FormView.DataBind,因此會觸發FormView的DataBound事件,在此呼叫GenCheckBox方法以動態產生CheckBoxList及其Items。
  3. 當使用者按下Update按鈕時,首先會觸發Page_Load事件,由於CheckBoxList是動態產生的,因此必須重新建立,所以筆者在Page_Load事件中再次呼叫GenCheckBox來產生CheckBoxList。
  4. 由於Update按鈕的CommandName設定為Update,因此Click時會觸發ItemUpdating事件,此時便能順利取得使用者於動態產生的CheckBoxList中所選擇的項目。

 

參考資料: