Addhandler, button.click not firing using VB.NET

耗尽温柔 提交于 2019-12-02 11:56:34

问题


I am experiencing a problem with buttons and AddHandler. It only works if I use AddHandler Button1.click, AddressOf... in Page_load, but if I create the button dynamically in one of the sub routines, the event doesn't fire.

For example,

<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

The dropdownlist works, but the button doesn't. What am I doing wrong?


回答1:


You have to regenerate your dynamically created controls on every postback (at last in Page_Load, better in Page_Init). You have to set the ID of the controls accordingly because ASP.Net needs it to identify which control caused a Postback and to handle the appropriate events.

You could save the number of created buttons in ViewState and use this to regenerate them on Page_Load. Increase the number when you add a new button. Use this number also to make the Button's ID unique(append it to the ID) to ensure that its the same on every postback.

For further informations, have a look the Page-Lifecycle and ViewState with dynamically added controls.

Edit: As Joel commented, if you only need one Button you can set it's ID statically, but you have to regenerate it on postback f.e. to handle its click-event.




回答2:


Just to aid anyone who has this problem and isn't quite sure how to implement. Here's a quick example. This example starts out by displaying a dropdownlist. When user selects something from the dropdown, another dropdownlist appears. I typed this off the top of my head, so it MAY contain errors, but you get the idea =)

In the aspx file, add a placeholder:

And in your codebehind: ...

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

...



来源:https://stackoverflow.com/questions/5233652/addhandler-button-click-not-firing-using-vb-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!