【问题标题】:Addhandler, button.click not firing using VB.NETAddhandler,button.click 不使用 VB.NET 触发
【发布时间】:2011-03-08 14:15:20
【问题描述】:

我遇到了按钮和 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

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

【问题讨论】:

    标签: asp.net vb.net button addhandler


    【解决方案1】:

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

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

    如需了解更多信息,请查看Page-LifecycleViewState with dynamically added controls

    编辑:正如 Joel 所说,如果您只需要一个 Button,您可以静态设置它的 ID,但您必须在回发 f.e. 时重新生成它。来处理它的点击事件。

    【讨论】:

    • +1 - 在这种情况下,由于没有迭代来生成动态控件,因此可以静态设置 ID。
    • 感谢您的回答,但我如何跟踪我创建的按钮(不止一个,这只是一个虚拟示例)?我的意思是,我知道我需要使用 ViewState,但是我无法传递要序列化的按钮,而且我不知道我应该给他们什么 ID。另一个问题,调试代码,看起来 DropDownList1_SelectedIndexChanged 中的代码在 Page_Load 之后执行,即使是响应 SelectedIndexChanged 事件。再次感谢
    • @user649904:正如我上面提到的,将已创建按钮的数量存储在 int-ViewState-Variable(f.e. "ButtonCount") 中,并在创建新按钮时增加它。在 page-init 中,您必须重新创建所有按钮(从 1 到 ButtonCount)并将它们添加到占位符。确保 ID 包含 Button 的索引(创建它时的 ButtonCount),以便它们在每次回发时获得相同的 ID。
    • 哇,你真快! :) 我正在动态创建一个 HtmlTable 并且我需要在特定行中添加按钮,每当需要修改该行的其他单元格中包含的信息时。我该怎么做?
    • @user649904:这听起来好像你应该从中创建另一个问题,或者至少编辑这个问题并提供更多信息/源代码,因为我不会(也不能)回答它在 cmets 中 ;) 我建议用另一个主题创建一个新主题。
    【解决方案2】:

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

    在 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
    

    ...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-19
      • 2012-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      相关资源
      最近更新 更多