您好我已经在这个问题上工作了几个星期,并且在此过程中已经研究了ASP页面生命周期,查看状态和其他主题以及大量相关帖子,以尝试提出解决方案。我已经取得了很大的进步,但已陷入僵局。
我已经使这个ASP应用程序尽可能简单,以便演示(对我自己)如何在表中动态添加和删除数据行。在初次访问该页面时,将向用户显示一个文本框和“添加”按钮。每次用户在tb中输入数据并单击“添加”时,就会插入一个ASP表(在占位符“Placeholder1”处)。该表包含先前输入的内容以及包含刚刚在文本框中输入的数据的新行(然后清除tb)。该表的每一行都有自己的“删除”按钮,单击该按钮时,将删除该行。
在幕后,在每个“添加”中,用户输入的数据将保存到数据表中,该数据表将保存到视图状态。在每个“删除”上,从数据表中删除该行,该数据表再次保存到视图状态。
我几乎让它工作了,但如果我删除一行然后尝试添加一行,则不会显示添加的行。我逐步完成了此用例的代码,并且ASP表似乎正确生成 - 添加的行没有显示。关于“删除”操作的一些事情搞砸了。
我已经读过,应该在Page_Init步骤中的每个回发上重建动态表,但是此步骤中的视图状态不可用,我需要检索数据表以了解要创建的行数,所以我正在Page_Load步骤中重建它。
非常感谢任何人的帮助!
这是.aspx:
<%@ Page Title="Home Page" Language="C#" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Dynamic Adding and Deleting of Rows in ASP Table Demo</title>
</head>
<body>
<form runat="server">
Please enter some text:<br /><br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Add" onclick="btnAdd_Click" /><br /><br />
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</form>
</body>
</html>
这是代码隐藏的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
int noOfRows = 0;
protected void Page_Init(object sender, EventArgs e)
{
}
protected void Page_Load(object sender, EventArgs e)
{
MakeTable();
}
/// <summary>
/// On first visit to page, create a data table (zero rows) in which to store user-entered data
/// If postback, create a new ASP table called "tblMyTable" of n rows where n = saved viewstate "NoOfRows"
/// and insert it into form at Placeholder1; each row of the ASP table contains a label (text to be added later)
/// and a "Delete" button
/// </summary>
private void MakeTable()
{
//On first visit to page...
if (!Page.IsPostBack)
{
DataTable myDataTable = new DataTable();
DataColumn myCol = myDataTable.Columns.Add();
myCol.DataType = System.Type.GetType("System.String");
ViewState["MyDataTable"] = myDataTable;
ViewState["NoOfRows"] = 0;
}
//On postback...
else
{
//Fetch number of rows from view state
noOfRows = (int)ViewState["NoOfRows"];
Table myTable = new Table();
myTable.ID = "tblMyTable";
TableRow myRow = null;
TableCell myCell = null;
Label myLabel = null;
Button myButton = null;
for (int i = 0; i < noOfRows + 1; i++)
{
myRow = new TableRow();
myCell = new TableCell();
myLabel = new Label();
myLabel.ID = "lblLabel" + i.ToString();
myCell.Controls.Add(myLabel);
myRow.Cells.Add(myCell);
myCell = new TableCell();
myButton = new Button();
myButton.ID = "btnDelete" + i.ToString();
myButton.Text = "Delete";
myButton.CommandName = "Delete";
//CommandArgument identifies the row number
myButton.CommandArgument = i.ToString();
myButton.Click += new EventHandler(btnDelete_Click);
myCell.Controls.Add(myButton);
myRow.Cells.Add(myCell);
myTable.Rows.Add(myRow);
}
PlaceHolder1.Controls.Add(myTable);
}
}
/// <summary>
/// Clicking on the form's Add button causes a new row to be added to data table, and the contents of the
/// text box are copied to this new row. The MyDataTable view state is saved, and the NoOfRows view state is
/// incremented by 1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnAdd_Click(object sender, EventArgs e)
{
DataTable myDataTable = (DataTable)ViewState["MyDataTable"];
if (TextBox1.Text != "")
{
DataRow myDataRow = myDataTable.NewRow();
myDataRow[0] = TextBox1.Text;
myDataTable.Rows.Add(myDataRow);
TextBox1.Text = "";
ViewState["MyDataTable"] = myDataTable;
noOfRows++;
ViewState["NoOfRows"] = noOfRows;
}
//Copy values from data table to labels in ASP table
FillTable(myDataTable);
}
/// <summary>
/// Each row in tblMyTable has a "Delete" button. When the Delete button is clicked, the corresponding row
/// in the data table is deleted, then the values in the data table are copied to the corresponding labels in
/// the ASP table, and then the last two rows of the ASP table are hidden
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void btnDelete_Click(object sender, EventArgs e)
{
Button myButton = (Button)sender;
//The row number is stored in each Delete button's CommandArgument
int thisRow = Convert.ToInt32(myButton.CommandArgument);
//Retrieve data table from view state, delete row, then save data table back to view state
DataTable myDataTable = (DataTable)ViewState["MyDataTable"];
myDataTable.Rows[thisRow].Delete();
ViewState["MyDataTable"] = myDataTable;
//Save NoOfRows view state, which is now 1 less than before Delete button was clicked
noOfRows = myDataTable.Rows.Count;
ViewState["NoOfRows"] = noOfRows;
//Copy data from data table to labels in ASP table
FillTable(myDataTable);
//Hide last two rows of ASP table
Table myTable = (Table)Page.Form.FindControl("tblMyTable");
myTable.Rows[myTable.Rows.Count - 1].Visible = false;
myTable.Rows[myTable.Rows.Count - 2].Visible = false;
}
/// <summary>
/// Fill the ASP table "tblMyTable" by setting each rows label equal to the corresponding value
/// in the data table "myDataTable"
/// </summary>
/// <param name="myDataTable"></param>
private void FillTable(DataTable myDataTable)
{
Table myTable = (Table)Page.Form.FindControl("tblMyTable");
Label myLabel = null;
for (int i = 0; i < noOfRows; i++)
{
myLabel = (Label)myTable.Rows[i].FindControl("lblLabel" + i.ToString());
myLabel.Text = myDataTable.Rows[i][0].ToString();
}
}
}
}