1

我遇到了按钮和 AddHandler 的问题。它仅在我在 Page_load 中使用 AddHandler Button1.click, AddressOf... 时才有效,但如果我在其中一个子例程中动态创建按钮,则不会触发该事件。

例如,

<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True">
    <asp:ListItem>1</asp:ListItem>
    <asp:ListItem>2</asp:ListItem>
</asp:DropDownList>
<asp:ScriptManager id="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel id="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="False">
    <contenttemplate>
        <asp:PlaceHolder id="PlaceHolder1" runat="server"></asp:PlaceHolder>
     </contenttemplate>
</asp:UpdatePanel>
<asp:UpdatePanel id="UpdatePanel2" runat="server" UpdateMode="Conditional">
    <contenttemplate>
        <asp:Label id="Label2" runat="server" Text="Label"></asp:Label>
    </contenttemplate>
</asp:UpdatePanel>


Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    Label1.Text = Date.Now
    ScriptManager1.RegisterAsyncPostBackControl(DropDownList1)
End Sub

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)
    Label2.Text = "Panel refreshed at " + Date.Now.ToString()
End Sub

Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged
    Dim b As New Button
    b.Text = "Click"
    ScriptManager1.RegisterAsyncPostBackControl(b)
    AddHandler b.Click, AddressOf Button1_Click
    PlaceHolder1.Controls.Add(b)
    UpdatePanel1.Update()
End Sub

下拉列表有效,但按钮无效。我究竟做错了什么?

4

2 回答 2

3

您必须在每次回发时重新生成动态创建的控件(最后在 Page_Load 中,在 Page_Init 中更好)。您必须相应地设置控件的 ID,因为 ASP.Net 需要它来识别导致回发的控件并处理适当的事件。

您可以在 ViewState 中保存已创建按钮的数量,并使用它在 Page_Load 上重新生成它们。添加新按钮时增加数字。使用此编号也可以使 Button 的 ID 唯一(将其附加到 ID)以确保它在每次回发时都相同。

有关更多信息,请查看带有动态添加控件的Page-LifecycleViewState

编辑:正如乔尔评论的那样,如果您只需要一个按钮,您可以静态设置它的 ID,但您必须在回发 fe 上重新生成它以处理其点击事件。

于 2011-03-08T14:45:36.610 回答
1

只是为了帮助任何有这个问题并且不太确定如何实施的人。这是一个简单的例子。此示例首先显示一个下拉列表。当用户从下拉列表中选择某些内容时,会出现另一个下拉列表。我在脑海中输入了这个,所以它可能包含错误,但你明白了 =)

在 aspx 文件中,添加一个占位符:

在您的代码隐藏中:...

Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init

    'Store control count in viewstate
    If Not IsPostBack Then ViewState("ControlCounter") = 1

    'Rebuild dynamic controls on every postback so when page's life cycle hits Page_Load, 
    'selected values in the viewstate (asp.net default behavior) can be loaded into the dropdowns
    Build_Dynamic_Controls()
End Sub

Protected Sub Build_Dynamic_Controls()

    'Clear placeholder
    myPlaceholder.Controls.Clear()

    'This is where the control counter stored in the viewstate comes into play
    For i as Integer = 0 To CInt(ViewState("ControlCounter") -1
        Dim ddlDynamic as New DropDownList With {
            .ID = "ddlDynamicDropdown" & i,
            .AutoPostBack = True
            }
        'This is the event that will be executed when the user changes a value on the form
        'and the postback occurs
        AddHandler ddlDynamic.SelectedIndexChanged, AddressOf ddlDynamic_SelectedIndexChanged

        'Add control to the placeholder
        myPlaceholder.Controls.Add(ddl)         

        'Put some values into the dropdown
        ddlDynamic.Items.Add("Value1")
        ddlDynamic.Items.Add("Value2")
        ddlDynamic.Items.Add("Value3")

    Next i
End Sub

Protected Sub ddlDynamic_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
    'When a dropdown value is changed, a postback is triggered (autopostback=true)
    'The event is captured here and we add another dropdown.

    'First we up the control count:
    ViewState("ControlCounter") = CInt(ViewState("ControlCounter")) + 1

    'Now that the "total controls counter" is upped by one, 
    'Let's recreate the controls in the placeholder to include the new dropdown
    Build_Dynamic_Controls()
End Sub

...

于 2011-10-20T15:43:15.303 回答