title: problems with postbacks events from dynamic controls in ASP.Net
body: <p>I am currently working on a page that has a user control that builds a dynamic table. The control is originally loaded on the Page_Init event, and any time that an event is raised that changes the dynamic control the table is reloaded. The problem here is that if the control is changed between between loads, the events from the control do not fire. For instance, there are originally two rows in the table. An item is added to the table during the postback and now there are four rows (this table adds two rows at a time). Each row has one or two buttons. When the page is loaded and sent back to the browser, if a user clicks on any of the buttons, a postback occurs, but the event does not fire. What am I doing wrong here? How can I tell what control/event caused the postback? Below is the code for both the page, and the user control.</p>
  
  <p><strong>Payments.aspx:</strong></p>
  
  <pre><code>Partial Public Class Payments
  Inherits BasePage
  
  Private foodMaster As Food
  Private _check As BusinessLayer.CustomerCheck
  
  Private Sub btnAddCheck_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddCheck.Click
      ' do nothing. the modal window is tied to the button via the modal window in the designer        
  End Sub
  
  Private Sub btnCalendar_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnCalendar.Click
      calCheckDate.Visible = Not calCheckDate.Visible
      modCheck.Show()
  End Sub
  
  Private Sub btnCheckSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCheckSave.Click
      Try
          If IsNothing(_check) Then _check = New BusinessLayer.CustomerCheck
          If Me.CurrentCheck &gt; 0 Then _check.CheckId = Me.CurrentCheck
          _check.CheckNumber = txtCheckNumber.Text
          _check.CheckDate = CDate(txtCheckDate.Text)
          _check.CheckAmount = CDbl(txtCheckAmount.Text)
          _check.DepositId = Me.CurrentDeposit
  
          _check.Save()
  
          LoadControls()
          ' reset the current check to not get confused after an edit
          Me.CurrentCheck = 0
          SetupNewCheck()
      Catch ex As Exception
          lblMessage.Text = "Could not save check."
          lblMessage.Visible = True
          modCheck.Show()
      End Try
  End Sub
  
  Private Sub calCheckDate_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles calCheckDate.SelectionChanged
      txtCheckDate.Text = calCheckDate.SelectedDate.ToShortDateString()
      calCheckDate.Visible = False
      modCheck.Show()
  End Sub
  
  Private Sub cvFutureDate_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles cvFutureDate.ServerValidate
      Try
          Dim depositDate As DateTime = DateTime.Parse(txtCheckDate.Text)
          Dim futureDate As DateTime = Now.AddDays(1)
          Dim tomorrow As New DateTime(futureDate.Year, futureDate.Month, futureDate.Day)
  
          args.IsValid = CBool(depositDate &lt; tomorrow)
      Catch
          args.IsValid = False
      End Try
  End Sub
  
  Private Sub cvInvalidAmount_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles cvInvalidAmount.ServerValidate
      Try
          Double.Parse(txtCheckAmount.Text)
      Catch
          args.IsValid = False
      End Try
  End Sub
  
  Private Sub cvInvalidDate_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles cvInvalidDate.ServerValidate
      Try
          DateTime.Parse(txtCheckDate.Text)
      Catch
          args.IsValid = False
      End Try
  End Sub
  
  Private Sub DepositEditing()
      foodMaster.Deposit.Load(Me.CurrentDeposit)
      foodMaster.ShowDepositWindow()
  End Sub
  
  Private Sub DepositSaved()
      dihHeader.Deposit.Load(Me.CurrentDeposit)
      dihHeader.Reload()
  End Sub
  
  Private Sub Payments_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
      LoadControls()
  End Sub
  
  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      foodMaster = DirectCast(Me.Master, Food)
      AddHandler foodMaster.SaveClicked, AddressOf DepositSaved
      AddHandler foodMaster.EditButtonClicked, AddressOf DepositEditing
  
      If IsPostBack = False Then
          Me.CurrentCheck = 0
          SetupNewCheck()
      End If
  End Sub
  
  Private Sub pcPayments_ApplyFundsClicked(ByVal CheckId As Integer) Handles pcPayments.ApplyFundsClicked
  
  End Sub
  
  Private Sub pcPayments_DeleteClicked(ByVal CheckId As Integer) Handles pcPayments.DeleteClicked
      Try
          If Me.CurrentCheck = CheckId Then Me.CurrentCheck = 0
          _check = New BusinessLayer.CustomerCheck
          _check.CheckId = CheckId
          _check.DeleteAllPayments()
          _check.Delete()
  
          LoadControls()
      Catch
  
      End Try
  End Sub
  
  Private Sub pcPayments_EditClicked(ByVal CheckId As Integer) Handles pcPayments.EditClicked
      Me.CurrentCheck = CheckId
      _check = New BusinessLayer.CustomerCheck(CheckId)
  
      txtCheckAmount.Text = _check.CheckAmount.ToString("0.00")
      txtCheckDate.Text = _check.CheckDate.ToShortDateString
      calCheckDate.SelectedDate = _check.CheckDate
      txtCheckNumber.Text = _check.CheckNumber
  
      modCheck.Show()
  End Sub
  
  Private Sub LoadControls()
      Dim checks As New BusinessLayer.CustomerCheckCollection()
      checks.LoadByDeposit(Me.CurrentDeposit)
      pcPayments.Checks = checks
      pcPayments.Reload()
  
      dihHeader.Deposit.Load(Me.CurrentDeposit)
      dihHeader.TotalCheckAmount = pcPayments.TotalCheckAmount
      dihHeader.TotalAppliedAmount = pcPayments.TotalAmountApplied
      dihHeader.Reload()
  End Sub
  
  Private Sub SetupNewCheck()
      _check = Nothing
      txtCheckDate.Text = Now.ToShortDateString()
      calCheckDate.SelectedDate = Now
  
      txtCheckAmount.Text = String.Empty
      txtCheckNumber.Text = String.Empty
  End Sub
  
  End Class
  </code></pre>
  
  <p><strong>PaymentsControl.ascx</strong></p>
  
  <pre><code>Public Partial Class PaymentsControl
  Inherits System.Web.UI.UserControl
  
  Private _checks As BusinessLayer.CustomerCheckCollection
  Private _applied As Double
  
  Public Event ApplyFundsClicked(ByVal CheckId As Integer)
  Public Event DeleteClicked(ByVal CheckId As Integer)
  Public Event EditClicked(ByVal CheckId As Integer)
  
  Public Sub New()
      _checks = New BusinessLayer.CustomerCheckCollection
      _applied = 0
  End Sub
  
  Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      'If IsPostBack = False Then
      '    BindChecks()
      'End If
  End Sub
  
  Private Sub ApplyButtonClicked(ByVal sender As Object, ByVal e As EventArgs)
      RaiseEvent ApplyFundsClicked(DirectCast(sender, LinkButton).CommandArgument)
  End Sub
  
  Private Sub DeleteButtonClicked(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs)
      RaiseEvent DeleteClicked(DirectCast(sender, ImageButton).CommandArgument)
  End Sub
  
  Private Sub EditButtonClicked(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs)
      RaiseEvent EditClicked(DirectCast(sender, ImageButton).CommandArgument)
  End Sub
  
  Private Sub BindChecks()
      tblChecks.Rows.Clear()
      tblChecks.Rows.Add(BuildTableHeader())
  
      _applied = 0
  
      For i As Int16 = 0 To _checks.Count - 1
          _checks(i).LoadAllPayments()
          _applied += _checks(i).TotalAmountApplied
  
          tblChecks.Rows.Add(BuildCheckRow(_checks(i)))
          tblChecks.Rows.Add(BuildInvoiceRow(_checks(i)))
      Next
  
      If tblChecks.Rows.Count = 1 Then tblChecks.Visible = False
  End Sub
  
  Private Function BuildCheckRow(ByVal Check As BusinessLayer.CustomerCheck) As TableRow
      Dim checkNumberCell As New TableCell()
      Dim checkDateCell As New TableCell()
      Dim checkAmountCell As New TableCell()
      Dim totalAppliedCell As New TableCell()
  
      checkNumberCell.Text = Check.CheckNumber
      checkDateCell.Text = Check.CheckDate.ToShortDateString()
      checkAmountCell.Text = Check.CheckAmount.ToString("C")
      totalAppliedCell.Text = Check.TotalAmountApplied.ToString("C")
      If Check.TotalAmountApplied &lt;&gt; Check.CheckAmount Then totalAppliedCell.ForeColor = Drawing.Color.Red
  
      Dim myRow As New TableRow
      myRow.Cells.Add(BuildCheckControlCell(Check.CheckId))
      myRow.Cells.Add(checkNumberCell)
      myRow.Cells.Add(checkDateCell)
      myRow.Cells.Add(checkAmountCell)
      myRow.Cells.Add(totalAppliedCell)
  
      Return myRow
  End Function
  
  Private Function BuildCheckControlCell(ByVal CheckId As Integer) As TableCell
      Dim editButton As New ImageButton()
      editButton.CommandArgument = CheckId
      editButton.CausesValidation = False
      editButton.AlternateText = "Edit"
      editButton.ImageUrl = "~/images/icons/bullet_edit.png"
      AddHandler editButton.Click, AddressOf EditButtonClicked
  
      Dim deleteButton As New ImageButton
      deleteButton.CommandArgument = CheckId
      deleteButton.CausesValidation = False
      deleteButton.AlternateText = "Delete"
      deleteButton.ImageUrl = "~/images/icons/bullet_cross.png"
      deleteButton.Attributes.Add("onclick", "return confirmDelete()")
      AddHandler deleteButton.Click, AddressOf DeleteButtonClicked
  
      Dim blankSpace As New Literal()
      blankSpace.Text = "&amp;nbsp;"
  
      Dim myCell As New TableCell
      myCell.Controls.Add(editButton)
      myCell.Controls.Add(blankSpace)
      myCell.Controls.Add(deleteButton)
  
      Return myCell
  End Function
  
  Private Function BuildInvoiceRow(ByVal Check As BusinessLayer.CustomerCheck) As TableRow
      Dim invoiceDetailCell As New TableCell
      invoiceDetailCell.ColumnSpan = 4
      invoiceDetailCell.Controls.Add(BuildInvoiceDetailTable(Check.Payments))
  
      Dim myRow As New TableRow
      myRow.Cells.Add(BuildInvoiceControlCell(Check.CheckId))
      myRow.Cells.Add(invoiceDetailCell)
  
      Return myRow
  End Function
  
  Private Function BuildInvoiceControlCell(ByVal CheckId As Integer) As TableCell
      Dim text As New Literal
      text.Text = "Invoices for check:&lt;br /&gt;"
  
      Dim applyButton As New LinkButton
      applyButton.CommandArgument = CheckId
      applyButton.CausesValidation = False
      applyButton.Text = "Apply Funds"
      AddHandler applyButton.Click, AddressOf ApplyButtonClicked
  
      Dim myCell As New TableCell
      myCell.Controls.Add(text)
      myCell.Controls.Add(applyButton)
  
      Return myCell
  End Function
  
  Private Function BuildInvoiceDetailTable(ByVal Payments As BusinessLayer.PaymentTransactionCollection) As Table
      Dim myTable As New Table
      myTable.CssClass = "tableSub"
      myTable.CellPadding = "0"
      myTable.CellSpacing = "0"
      myTable.BorderWidth = "0"
      myTable.Rows.Add(BuildInvoiceDetailHeader())
  
      For i As Integer = 0 To Payments.Count - 1
          myTable.Rows.Add(BuildPaymentRow(Payments(i)))
      Next
  
      If myTable.Rows.Count = 1 Then myTable.Visible = False
  
      Return myTable
  End Function
  
  Private Function BuildInvoiceDetailHeader() As TableRow
      Dim customerCell As New TableHeaderCell
      Dim invoiceCell As New TableHeaderCell
      Dim dueCell As New TableHeaderCell
      Dim paymentCell As New TableHeaderCell
  
      customerCell.Text = "Customer"
      invoiceCell.Text = "Invoice number"
      dueCell.Text = "Amount due"
      paymentCell.Text = "Payment amount"
  
      Dim myRow As New TableRow
      myRow.Cells.Add(customerCell)
      myRow.Cells.Add(invoiceCell)
      myRow.Cells.Add(dueCell)
      myRow.Cells.Add(paymentCell)
  
      Return myRow
  End Function
  
  Private Function BuildPaymentRow(ByVal Payment As BusinessLayer.PaymentTransaction) As TableRow
      Dim customerCell As New TableCell
      Dim invoiceCell As New TableCell
      Dim amountDueCell As New TableCell
      Dim paymentCell As New TableCell
  
      'Payment.Customer.Load()
      customerCell.Text = Payment.Customer.NumberAndName
      invoiceCell.Text = Payment.Invoice.InvoiceNumber
      amountDueCell.Text = Payment.Invoice.AmountDue.ToString("C")
      paymentCell.Text = Payment.PaymentAmount.ToString("C")
  
      Dim myRow As New TableRow
      myRow.Cells.Add(customerCell)
      myRow.Cells.Add(invoiceCell)
      myRow.Cells.Add(amountDueCell)
      myRow.Cells.Add(paymentCell)
  
      Return myRow
  End Function
  
  Private Function BuildTableHeader() As TableRow
      Dim blankCell As New TableHeaderCell()
      Dim checkNumberCell As New TableHeaderCell()
      Dim checkDateCell As New TableHeaderCell()
      Dim checkAmountCell As New TableHeaderCell()
      Dim totalUnappliedCell As New TableHeaderCell()
  
      checkNumberCell.Text = "Check number"
      checkDateCell.Text = "Check date"
      checkAmountCell.Text = "Check amount"
      totalUnappliedCell.Text = "Total unapplied"
  
      Dim myRow As New TableRow
      myRow.Cells.Add(blankCell)
      myRow.Cells.Add(checkNumberCell)
      myRow.Cells.Add(checkDateCell)
      myRow.Cells.Add(checkAmountCell)
      myRow.Cells.Add(totalUnappliedCell)
  
      Return myRow
  End Function
  
  Public Sub Reload()
      BindChecks()
  End Sub
  
  Public Property Checks() As BusinessLayer.CustomerCheckCollection
      Get
          Return _checks
      End Get
      Set(ByVal value As BusinessLayer.CustomerCheckCollection)
          _checks = value
      End Set
  End Property
  
  Public ReadOnly Property TotalCheckAmount() As Double
      Get
          Return _checks.TotalCheckAmount
      End Get
  End Property
  
  Public ReadOnly Property TotalAmountApplied() As Double
      Get
          Return _applied
      End Get
  End Property
  
  End Class
  </code></pre>