Question

I've asked this before, but sadly I'm still having issues and the issue wasn't resolved. Basically, I'm dynamically creating a LinkButton for each row of a table I am generating, and that button has the task of deleting the row with the corresponding ID from the database. To do this, I seemingly need to assign the LinkButton a Command so it'll go into the event when it is clicked. Problem is, when the button's clicked the program never goes into the command - I've put breakpoints in there and it never goes into them. Here's my code:

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);
                }
            }
    }

Note I've commented out 2 of the crucial lines for posting here, just to point out that I've tried both of the lines that's commented out, and neither work :(

Was it helpful?

Solution

You need to add the controls on every postback. You appear to be only creating them on the initial get (that query string check). On the post back, those controls never get recreated so no event fires.

It's notoriously counter-intuitive, but while ASP.NET bends over backwards to make you think that the instance of your page class is the same between two HTTP requests, the reality is that they are not the same. A new instance is created each time. It looks like you are trying to avoid adding the dynamically generated controls multiple times -- thinking you don't want duplicates. The reality is that you will never get duplicates when adding dynamically generated controls in a life-cycle method such as OnInit() since it's always a new instance of the page class, and thus those dynamically generated controls are gone.

The reason this is usually transparent to developers is that all the controls in the code-front are automatically re-generated for you on both the initial request and every single post-back. For your dynamically created controls, you happen to have this line:

if (Request.QueryString["id"] != null) { ... }

Unless you're doing something special, that "id" attribute will not be in the query string on the postback. This means that none of the code in the if block will be run on the post back (when your event actually fires.) This means that your if-check at the top should be removed altogether. All that code should run for each and every request (GET and POST).

OTHER TIPS

Just saying I've created a workaround - simply creating a simple link to the page, along with a query string containing the id of the row to delete

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top