9

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

就上下文而言,UC 被称为“Whereas”,因为它们是决议中的 WHEREAS 子句。这是代码,仅缩减到相关内容:

编辑.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>
...

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

而.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
4

2 回答 2

0

当文档大纲发生变化时,更新面板的行为通常很奇怪。尝试将“添加”按钮移到面板外,然后在更新面板的“触发器”部分添加该按钮。

于 2013-02-14T16:23:21.007 回答
0

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

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

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

于 2013-02-14T17:25:04.597 回答