UpdatePanel中的按钮随机丢失事件处理程序

Jos*_*ley 9 vb.net asp.net events updatepanel

在ASP.NET网页上,我有一个UpdatePanel.在这个UpdatePanel中,我有一个"添加"按钮,可以动态地将我创建的任何数量的用户控件添加到PlaceHolder.用户控件包含标签,按钮和第三方控件.用户控件内的按钮用于从父面板中删除该特定用户控件."添加"和"删除"功能都可以正常工作.但是,"添加"按钮上的事件处理程序有时会停止工作,没有明显的模式或原因.如果我添加2个UC并删除1,有时"添加"按钮会继续工作,有时则不会.寻找原因的任何步骤都会有所帮助.

对于上下文,UC被称为"Whereas",因为它们是解析中的WHEREAS子句.以下是代码,仅限于相关内容:

Edit.aspx

...
<asp:ScriptManager ID="sm1" runat="server"></asp:ScriptManager>
<asp:Panel ID="pnlMain" runat="server">
    <div class="form-horizontal">
        <asp:UpdatePanel ID="upnlWhereas" runat="server">
            <ContentTemplate>
                <asp:PlaceHolder ID="phWhereas" runat="server"></asp:PlaceHolder>
                <div class="control-group">
                    <asp:Label ID="lblAddWhereas" AssociatedControlID="btnAdd1Whereas" CssClass="control-label" runat="server"></asp:Label>
                    <div class="controls">
                        <asp:Button ID="btnAdd1Whereas" CssClass="btn" UseSubmitBehavior="false" Text="Add Whereas" runat="server" />
                    </div>
                </div>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
</asp:Panel>
...
Run Code Online (Sandbox Code Playgroud)

Edit.aspx.vb(类是Edit2)

...
Private Property ControlsList As List(Of String)
    Get
        If ViewState("ControlsList") Is Nothing Then
            ViewState("ControlsList") = New List(Of String)
        End If

        Return CType(ViewState("ControlsList"), List(Of String))
    End Get
    Set(ByVal Value As List(Of String))
        ViewState("ControlsList") = Value
    End Set
End Property

Private ReadOnly Property NextID As Integer
    Get
        Return ControlsList.Count + 1
    End Get
End Property

Protected Overrides Sub LoadViewState(savedState As Object)
    MyBase.LoadViewState(savedState)

    For Each waID As String In ControlsList
        Dim NewWhereas As Whereas
        NewWhereas = Me.LoadControl("~/UserControls/Whereas.ascx")

        NewWhereas.ID = waID
        phWhereas.Controls.Add(NewWhereas)

        AddHandler NewWhereas.OnRemoveWhereasClick, AddressOf Whereas_OnRemoveWhereasClick
    Next
End Sub

...

Private Sub btnAdd1Whereas_Click(sender As Object, e As System.EventArgs) Handles btnAdd1Whereas.Click
    Dim NewWhereas As Whereas
    NewWhereas = Me.LoadControl("~/UserControls/Whereas.ascx")

    NewWhereas.ID = "wa" + NextID.ToString
    phWhereas.Controls.Add(NewWhereas)

    ControlsList.Add(NewWhereas.ID)
End Sub

Private Sub Whereas_OnRemoveWhereasClick(ByVal sender As Object)
    Dim thisButton As Button = sender
    Dim thisWhereas As Whereas = thisButton.Parent.Parent

    phWhereas.Controls.Remove(thisWhereas)
    ControlsList.Remove(thisWhereas.ID)
End Sub
...
Run Code Online (Sandbox Code Playgroud)

Whereas.ascx.vb

Public Delegate Sub ActionClick(ByVal sender As Object)

Public Class Whereas
    Inherits System.Web.UI.UserControl

    ...

    Public Event OnRemoveWhereasClick As ActionClick

    Public Sub btnRemoveWhereas_Click(ByVal sender As Object, ByVal e As EventArgs)
        RaiseEvent OnRemvoeWhereasClick(sender)
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

Jos*_*ley 0

禁用UpdatePanel后(感谢Yellowfog的建议),我发现发生了以下情况:

  1. 单击“添加”将添加 ID 为“wa1”的用户控件。
  2. 再次单击“添加”将计算列表中现有用户控件的数量,并添加 ID 为“wa2”的用户控件。
  3. 单击控件“wa1”上的“删除”将删除“wa1”。
  4. 单击“添加”将计算列表中现有用户控件的数量 (1),并尝试添加 ID 为“wa2”的用户控件,这将导致错误,因为该控件已存在于页面上。由于调用是异步的,因此未显示此错误。

解决方案是根据列表中控件的数量使用 GUID 而不是整数来生成动态添加的用户控件的 ID。这样它们基本上就可以保证是唯一的。