2009-08-25 8 views
1

現在、動的テーブルを作成するユーザーコントロールを持つページを作成しています。このコントロールは、もともとPage_Initイベントにロードされています。動的コントロールを変更するイベントが発生すると、いつでもテーブルがリロードされます。ここでの問題は、制御が負荷の間で変更された場合、制御からのイベントは発生しないことです。たとえば、もともとテーブルには2つの行があります。ポストバック中にアイテムがテーブルに追加され、今度は4つの行があります(このテーブルは一度に2つの行を追加します)。各行には1つまたは2つのボタンがあります。ページがロードされてブラウザに返されると、ユーザーがいずれかのボタンをクリックするとポストバックが発生しますが、イベントは発生しません。私はここで間違って何をしていますか?どのようなコントロール/イベントがポストバックを引き起こしたのかをどのように伝えることができますか?以下は、ページとユーザーコントロールの両方のコードです。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

関連する問題