【发布时间】:2025-12-25 21:05:16
【问题描述】:
我有一个 GridView,我通过 button_OnClick 事件动态添加行,这会从 DropDownList 添加一个带有产品名称和产品 ID 的新行,并且还包含一个带有空文本框的列供用户输入。
我的问题是,当我测试它并在文本框中输入数据,然后添加另一个产品时,回发导致我的数据丢失(正确的行数仍然存在产品名称/ID)。
<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 { 获取 {return ViewState["ProductDataTable"] 作为 DataTable ??新数据表(); } 设置 { 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 事件中,如果它不是 PostBack 也有一个空列表的绑定
grdSelectedProducts.DataSource = new List<Products>();
grdSelectedProducts.DataBind();
【问题讨论】:
-
如何在 GridView 中添加数据
-
@Adil 我已经更新了帖子。
-
当 btnAddProduct 回发时,您在 GridView 中没有得到记录吗?您是否也将 GridView 绑定到其他任何地方?
-
Page_load 事件中有一个绑定,它将一个空列表绑定到网格,并且在删除一行时有绑定,但除此之外别无他法。我再次更新了正文。
-
能否请您将 page_load 也添加到代码中。以及您如何存储文本数据。你把它推到数据库然后拉回来吗?