2009-08-25 77 views
1

我目前正在研究一個具有構建動態表的用戶控件的頁面。該控件最初加載在Page_Init事件中,並且任何時候發生的事件都會改變動態控件的表格重新加載。這裏的問題是,如果控件在兩次加載之間發生變化,控件的事件不會觸發。例如,表格中最初有兩行。一個項目在回發期間添加到表中,現在有四行(此表一次添加兩行)。每行有一個或兩個按鈕。當頁面被加載併發送回瀏覽器時,如果用戶點擊任何按鈕,就會發生回發,但事件不會觸發。我在這裏做錯了什麼?我怎麼知道哪些控件/事件導致了回發?以下是頁面和用戶控件的代碼。ASP.Net中的動態控件的回發事件的問題

Payments.aspx:

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 > 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 < 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 

PaymentsControl.ascx

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 <> 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 = "&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:<br />" 

    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 

回答

1

您需要Id屬性分配給每個動態添加服務器控件,這將有助於達到回發事件。此外,在回發時,我相信動態添加的控件需要使用相同的ID重新創建,以便回發方法和視圖狀態正常運行。

+1

我認爲你在那裏是正確的道路。我一直在想,它在找到控制權時遇到了問題,而且沒有一個id是有道理的。 但是,我不能停留太久,所以我重新使用中繼器的控制,一切工作正常。 我想我需要將你的回答標記爲答案。謝謝你的幫助。 – fizch 2009-08-25 19:48:50