9

ASP.NET Web ページに UpdatePanel があります。この UpdatePanel 内には、作成した任意の数のユーザー コントロールを PlaceHolder に動的に追加する「追加」ボタンがあります。ユーザー コントロールには、ラベル、ボタン、およびサードパーティ製のコントロールが含まれています。ユーザー コントロール内のボタンは、親パネルから特定のユーザー コントロールを削除するためのものです。「追加」と「削除」の両方の機能が正しく機能します。ただし、[追加] ボタンのイベント ハンドラーは、明らかなパターンや原因がなく動作を停止することがあります。2 つの UC を追加して 1 つを削除すると、[追加] ボタンが引き続き機能する場合と機能しない場合があります。原因を見つけるための一歩は役に立ちます。

コンテキストでは、UC は解決の WHEREAS 句であるため、「Whreas」と呼ばれます。関連するコンテンツのみに切り詰めたコードを次に示します。

編集.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 に答える