2009-08-25 3 views
1

Je travaille actuellement sur une page qui a un contrôle utilisateur qui crée une table dynamique. Le contrôle est à l'origine chargé sur l'événement Page_Init et chaque fois qu'un événement est déclenché qui modifie le contrôle dynamique, la table est rechargée. Le problème ici est que si le contrôle est changé entre les charges, les événements du contrôle ne se déclenchent pas. Par exemple, il y a deux rangées dans la table à l'origine. Un élément est ajouté à la table pendant la publication et maintenant il y a quatre lignes (cette table ajoute deux lignes à la fois). Chaque rangée a un ou deux boutons. Lorsque la page est chargée et renvoyée au navigateur, si un utilisateur clique sur l'un des boutons, une publication se produit, mais l'événement ne se déclenche pas. Qu'est-ce que je fais mal ici? Comment puis-je savoir quel contrôle/événement a causé la publication? Voici le code pour la page et le contrôle de l'utilisateur.Problèmes avec les événements de publication à partir des contrôles dynamiques dans 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 

Répondre

1

Vous devez attribuer la propriété Id à chaque contrôle du serveur ajouté dynamiquement qui desservira des événements postback. En outre, lors de la publication, je crois que les contrôles ajoutés dynamiquement doivent être recréés avec le même identifiant afin que les méthodes de publication et viewstate fonctionnent correctement.

+1

Je pense que vous êtes sur le bon chemin là-bas. Je pensais qu'il avait des problèmes pour trouver le contrôle, et ne pas avoir un identifiant a du sens. Cependant, je ne peux pas rester inactif trop longtemps, j'ai donc recréé le contrôle en utilisant des répéteurs et tout fonctionne correctement. Je suppose que je dois marquer votre réponse comme réponse. Merci de votre aide. – fizch

Questions connexes