2014-03-27 31 views
0

我有一個GridView,我通過button_OnClick事件動態添加行,這會添加一個新行,產品名稱爲& DropDownList中的產品ID,並且還包含一個帶有空文本的列用於用戶輸入的框。在GridView中停止文本框在回發中丟失數據

我的問題是,當我測試它,並在文本框中輸入數據,然後添加另一個產品,回發導致我的數據丟失(正確的行數仍然存在與產品名稱/ ids)。

      <asp:GridView runat="server" ID="grdSelectedProducts" BorderWidth="1px" CellPadding="3" CellSpacing="2" AutoGenerateColumns="False" OnRowDataBound="grdSelectedProducts_OnRowDataBound" ShowHeaderWhenEmpty="True" DataKeyNames="ProductId" 
           OnRowCommand="grdSelectedProducts_RowCommand" OnRowDeleted="grdSelectedProducts_RowDeleted" OnRowDeleting="grdSelectedProducts_RowDeleting" EmptyDataText="Please select a Product and click 'Add'" EnableViewState="True"> 
           <Columns> 
            <asp:BoundField DataField="Product" HeaderText="Product" ReadOnly="False"/> 
            <asp:TemplateField HeaderText="Description"> 
             <ItemTemplate> 
               <asp:TextBox runat="server" ID="txtDescriptionEntry" Text="" style="width:98% !important" EnableViewState="True"></asp:TextBox> 
             </ItemTemplate> 
            </asp:TemplateField> 
            <asp:TemplateField> 
             <ItemTemplate> 
              <asp:LinkButton runat="server" ID="linkDelete" runat="server" CommandName="Delete" CommandArgument="<%# Container.DataItemIndex %>">Remove</asp:LinkButton> 
             </ItemTemplate> 
            </asp:TemplateField> 
            <asp:BoundField DataField="ProductId" HeaderText="ProductId" ReadOnly="False" Visible="False" /> 
           </Columns> 
          </asp:GridView> 

如何避免回發報廢創建的每個txtDescriptionEntry上的數據?可能有0到這些文本框的數量是無限的,所以我在任何時候都不會有確切的名字。

編輯,按照評論下面,我包括我怎麼行添加到網格代碼: 私人數據表ProductDataTable { {返回的ViewState [「ProductDataTable」]作爲數據表?新的DataTable(); } set {ViewState [「ProductDataTable」] = value; }}

private DataTable CreateDataTable(bool isAddingValue, string selectedProduct, string selectedId) 
    { 
     // if isAddingValue is FALSE then it isn't from a button click to add a Product, it is just 
     // a call to create the datatable 

     DataTable dataTable = ProductDataTable; 
     if (!dataTable.Columns.Contains("Product")) 
     { 
      dataTable.Columns.Add("Product"); 
      dataTable.Columns.Add("Description"); // This column is free format text that the user enters. 
      dataTable.Columns.Add("ProductId"); 
     } 

     if (isAddingValue) 
     { 
      // Get the data from ViewState 
      //dataTable = ProductDataTable; 
      DataRow dataRow; 
      dataRow = dataTable.NewRow(); 
      dataRow["Product"] = selectedProduct; 
      dataRow["ProductId"] = selectedId; 
      dataTable.Rows.Add(dataRow); 
     } 
     else 
     { 
      grdSelectedProducts.DataSource = null; 
      grdSelectedProducts.DataSource = ProductDataTable; 
      grdSelectedProducts.DataBind(); 

     } 
     // Save the data back to ViewState 
     ProductDataTable = dataTable; 

     return dataTable; 
    } 

    protected void btnAddProduct_OnClick(object sender, EventArgs e) 
    { 
     string selectedProduct = ddlProduct.SelectedItem.Text; 
     string selectedId = ddlProduct.SelectedValue; 

     DataTable dataTable = CreateDataTable(true, selectedProduct, selectedId); 

     grdSelectedProducts.DataSource = dataTable; 
     grdSelectedProducts.DataBind(); 

    } 

    protected void grdSelectedProducts_RowCommand(object sender, GridViewCommandEventArgs e) 
    { 
     if (e.CommandName == "Delete") 
     { 
      if (!string.IsNullOrEmpty(e.CommandArgument.ToString())) 
      { 
       int rowIndex = Convert.ToInt32(e.CommandArgument); 
       DataTable table = CreateDataTable(false, string.Empty, string.Empty); 
       table.Rows.RemoveAt(rowIndex); 
       grdSelectedProducts.DataSource = table; 
       grdSelectedProducts.DataBind(); 
      } 
     } 
    } 

而在Page_Load事件中,如果不是回發有還結合空列表

 grdSelectedProducts.DataSource = new List<Products>(); 
     grdSelectedProducts.DataBind(); 
+0

如何在GridView中添加數據 – Adil

+0

@Adil我已更新帖子。 – MattR

+0

當btnAddProduct做回發時,你不在GridView中獲取記錄嗎?你還在其他地方綁定了GridView嗎? – Adil

回答

0

我想通了這一點,不是最好的解決方案(所以我可能不會推薦它),但它讓我擺脫了困境。

我用OnRowDataBound事件,以便爲正在綁定到表的每一行我會使用RowIndex才能獲得相應的行中的DataTable,然後,我會指定文本框(經指數也獲得)的值來自DT。下面的例子。

protected void grdSelectedproducts_OnRowDataBound(object sender, GridViewRowEventArgs e) 
    { 
     if (e.Row.RowIndex > -1) 
     { 
      TextBox txtDescription = e.Row.FindControl("txtDescriptionEntry") as TextBox; 

      if (txtDescription != null) 
      { 
       DataTable dt = ProductDataTable; 
       DataRow row = dt.Rows[e.Row.RowIndex] as DataRow; 
       txtDescription.Text = row[1].ToString(); 
      } 
     } 
    }