之前我曾经问过这个问题,但遗憾的是我仍然遇到问题而且问题没有得到解决。基本上,我正在为我生成的表的每一行动态创建一个LinkButton,该按钮的任务是从数据库中删除具有相应ID的行。要做到这一点,我似乎需要为LinkButton分配一个命令,以便它在单击时进入事件。问题是,当按钮单击时,程序从不进入命令 - 我在那里放置了断点,它永远不会进入它们。这是我的代码:
protected void Page_Init(object sender, EventArgs e)
{
if (Request.QueryString["id"] != null)
{
ColorConverter conv = new ColorConverter();
string connection = ConfigurationManager.ConnectionStrings["TPRTestConnectionString"].ConnectionString;
TPRDBDataContext dc = new TPRDBDataContext();
DataContext db = new DataContext(connection);
Table<SageAccount> SageAccount = db.GetTable<SageAccount>();
Table<InvoiceItem> InvoiceItem = db.GetTable<InvoiceItem>();
Table<Invoice> Invoice = db.GetTable<Invoice>();
Boolean alloweditting = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s.alloweditting).Single();
if (alloweditting == false)
{
dtlsInsert.Visible = false;
modalPanel.Visible = false;
}
int sagepk = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s.sageaccount).Single();
lblSageID.Text = (from s in dc.SageAccounts where s.ID == sagepk select s.SageID).Single();
lblDate.Text = DateTime.Now.ToShortDateString();
Table table = new Table();
table.Width = Unit.Percentage(100);
table.GridLines = (GridLines)3;
TableHeaderRow header = new TableHeaderRow();
header.BackColor = (System.Drawing.Color)conv.ConvertFromString("#EDEDED");
foreach (string header2 in new string[] { "", "Quantity", "Rate", "Description", "Nominal Code", "Subtotal" })
{
TableCell cell = new TableCell();
cell.Text = header2;
header.Cells.Add(cell);
}
table.Rows.Add(header);
var data = (from s in dc.InvoiceItems where s.invoiceid.ToString() == Request.QueryString["id"].ToString() select s);
foreach (var x in data)
{
TableRow row = new TableRow();
if (x.invoicetext == null)
{
decimal total;
try
{
total = (decimal)x.rate * (decimal)x.quantity;
}
catch
{
total = 0;
}
int i = 0;
foreach (string columnData in new string[] { x.id.ToString(), x.quantity.ToString(), x.rate.ToString(), x.description, x.nominalcode, total.ToString("N2") })
{
TableCell cell = new TableCell();
{
if (i == 0)
{
LinkButton lnkdel = new LinkButton();
lnkdel.Text = "Delete";
lnkdel.ID = "lnkDel" + Guid.NewGuid();
if (alloweditting == false)
{
lnkdel.Enabled = false;
}
lnkdel.Font.Bold = false;
lnkdel.CommandArgument = x.id.ToString();
//lnkdel.Command += lnkdel_Command;
//lnkdel.Command += new CommandEventHandler(this.lnkdel);
cell.Controls.Add(lnkdel);
i++;
}
else
{
cell.Text = columnData;
}
}
row.Cells.Add(cell);
}
runningtotal = runningtotal + total;
}
else
{
int i = 0;
foreach (string columnData in new string[] { x.id.ToString(), x.invoicetext })
{
TableCell cell = new TableCell();
if (i == 0)
{
LinkButton lnkdel = new LinkButton();
lnkdel.Text = "Delete";
lnkdel.ID = "lnkDel" + Guid.NewGuid();
if (alloweditting == false)
{
lnkdel.Enabled = false;
}
lnkdel.Font.Bold = false;
//lnkdel.Command += lnkdel_Command;
//lnkdel.Command += new CommandEventHandler(this.lnkdel);
lnkdel.CommandArgument = x.id.ToString();
cell.Controls.Add(lnkdel);
i++;
}
else
{
cell.Text = columnData;
cell.ColumnSpan = 5;
}
row.Cells.Add(cell);
}
}
switch (x.formatoptions)
{
case 1:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("black");
row.Font.Bold = false;
break;
case 2:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("black");
row.Font.Bold = true;
break;
case 3:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("red");
row.Font.Bold = false;
break;
case 4:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("red");
row.Font.Bold = true;
break;
}
table.Rows.Add(row);
}
TableFooterRow row2 = new TableFooterRow();
TableCell cell2 = new TableCell();
cell2.Text = "<span style\"text-align: right; width: 100%;\">Total = <b>" + runningtotal.ToString("N2") + "</b></span>";
cell2.ColumnSpan = 6;
row2.Cells.Add(cell2);
table.Rows.Add(row2);
var update = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s).Single();
update.total = runningtotal;
dc.SubmitChanges();
datatable.Controls.Clear();
datatable.Controls.Add(table);
}
else
{
Response.Redirect("Invoices.aspx");
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void lnkdel_Command(object sender, CommandEventArgs e)
{
string connection = ConfigurationManager.ConnectionStrings["TPRTestConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connection))
{
SqlCommand comm = new SqlCommand("DELETE FROM InvoiceItem WHERE id = @id", conn);
comm.Parameters.AddWithValue("@id", e.CommandArgument.ToString());
conn.Open();
try
{
comm.ExecuteNonQuery();
}
catch (Exception ex)
{
Response.Write(ex);
}
}
}
注意我已经在这里发表了两条关键的评论栏,只是为了指出我已经尝试了两条被注释掉的行,但都没有工作:(
答案 0 :(得分:1)
您需要在每次回发时添加控件。您似乎只是在初始get(查询字符串检查)上创建它们。在帖子后面,这些控件永远不会重新创建,因此不会触发任何事件。
这是出了名的反直觉,但是当ASP.NET向后弯曲以使您认为两个HTTP请求之间的页面类实例相同时,实际情况是它们不一样。每次都会创建一个新实例。看起来你试图避免多次添加动态生成的控件 - 认为你不想要重复。实际情况是,在OnInit()
等生命周期方法中添加动态生成的控件时,永远不会获取重复项,因为它始终是页面类的新实例,因此它们是动态生成的控制消失了。
这对开发人员来说通常是透明的原因是代码前端的所有控件都会在初始请求和每个回发时自动重新生成。对于动态创建的控件,您碰巧有这一行:
if (Request.QueryString["id"] != null) { ... }
除非您正在做一些特殊的事情,否则“id”属性将不会出现在回发的查询字符串中。这意味着if
块中的任何代码都不会在帖子后面运行(当您的事件实际触发时)。这意味着您的if
- 顶部检查应该完全删除。 所有代码应针对每个请求运行(GET 和 POST)。
答案 1 :(得分:0)
只是说我已经创建了一个解决方法 - 只需创建一个指向该页面的简单链接,以及一个包含要删除的行的ID的查询字符串