首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >动态事件处理程序不触发

动态事件处理程序不触发
EN

Stack Overflow用户
提问于 2013-10-25 19:39:53
回答 2查看 7.7K关注 0票数 4

我希望根据用户输入文本框的数字动态创建大量控件。这个部分我工作得很好,但我也需要动态创建的文本框来拥有自己的事件处理程序,这样用户就可以在其中输入一个数字,并创建更多的控件。

我的问题是,我为这些控件设置的事件处理程序不会触发。也许我没有正确理解ASP.NET页面的生命周期,但我目前正在OnInit事件中生成动态控件(在第一个文本框的TextChanged事件中生成这些控件之前,但根据我在这里发现的OnInit事件的建议切换到使用OnInit事件:Dynamically Added Event Handler Not Firing)。

编辑

我删除了我最初发布的代码,因为否则这个帖子就太长了。

我要发布我的全部.aspx代码和后面的代码,所以你们知道这正是我所看到的。同样,当在代码中更改文本时,由此代码生成的动态TextBox不会触发绑定到它的事件处理程序,因此它就会消失。有趣的是-我认为当您更改文本时确实会发生回发,但它不会触发事件处理程序.

ASPX前端:

代码语言:javascript
运行
复制
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <div id="dynamicControlDiv">
            <asp:Label ID="lblEnter" runat="server" Text="Enter the amount of textboxes you want:"></asp:Label>
            <asp:TextBox ID="txtEnter" runat="server" AutoPostBack="true"></asp:TextBox>
            <asp:Label ID="lblConfirm" runat="server" Text=""></asp:Label>
        </div>
    </form>
</body>
</html>

背后的代码:

部分类_Default继承System.Web.UI.Page

代码语言:javascript
运行
复制
Dim numOfDesiredControls As Int16

Protected Sub txtEnter_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtEnter.TextChanged

    Try
        numOfDesiredControls = Convert.ToInt16(txtEnter.Text)
        If Not numOfDesiredControls = 0 Then
            For i As Int16 = 1 To numOfDesiredControls
                Dim txtTest As New TextBox
                txtTest.Text = "dynamicTextBox"
                txtTest.ID = "dynamicTextBox" + i.ToString
                txtTest.AutoPostBack = True
                Form.Controls.Add(txtTest)
                AddHandler txtTest.TextChanged, AddressOf dynamicEventHandler
            Next
        End If
    Catch ex As Exception

    End Try
End Sub

Protected Sub dynamicEventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
    ' If the event handler gets fired, reflect this by changing the text of lblConfirm
    lblConfirm.Visible = True
    lblConfirm.Text = "Event handler fired!"
End Sub

End Class

尝试使用此代码创建您自己的项目,看看您是否遇到了与我相同的问题--动态创建的TextBox帖子返回,但不触发它的事件处理程序,然后TextBox从页面中消失.再次感谢你的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-25 20:13:48

由于ViewState的存在,动态控件可能有点棘手。

基本上:您是在响应TextChanged事件时添加动态控件,该事件在InitLoad之后以及ViewState反序列化之后触发。因此,您正经历这个问题,因为ViewState不知道动态控件,并且与您的期望不同步。通过在txtEnter.Text阶段检查Load的值并在那里创建控件,您可以让ViewState知道控件(记住,每次页面加载时都会创建这些控件),因此您的dynamicEventHandler现在有了要执行的上下文。

下面是经过更正的代码(但作为一个带有嵌入式VB的文件,为了简单起见,您当然可以将其分离到一个代码隐藏文件中):

代码语言:javascript
运行
复制
<%@ Page Language="VB" AutoEventWireup="false" %>

<script runat="server">
    Dim numOfDesiredControls As Int16

    Protected Sub Page_Load() Handles form1.Load

        Try
            numOfDesiredControls = Convert.ToInt16(txtEnter.Text)
            If Not numOfDesiredControls = 0 Then
                For i As Int16 = 1 To numOfDesiredControls
                    Dim txtTest As New TextBox
                    txtTest.Text = "dynamicTextBox"
                    txtTest.ID = "dynamicTextBox" + i.ToString
                    txtTest.AutoPostBack = True
                    ' txtTest.EnableViewState = False
                    Form.Controls.Add(txtTest)
                    AddHandler txtTest.TextChanged, AddressOf dynamicEventHandler
                Next
            End If
        Catch ex As Exception

        End Try
    End Sub

    Protected Sub dynamicEventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
        ' If the event handler gets fired, reflect this by changing the text of lblConfirm
        Dim txt As TextBox
        txt = CType(sender, TextBox)
        lblConfirm.Visible = True
        lblConfirm.Text = "Event handler " + txt.Id + " fired: " + txt.Text ' append ID and text so we know which one fired it.
    End Sub
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <div id="dynamicControlDiv">
            <asp:Label ID="lblEnter" runat="server" Text="Enter the amount of textboxes you want:"></asp:Label>
            <asp:TextBox ID="txtEnter" runat="server" AutoPostBack="true"></asp:TextBox>
            <asp:Label ID="lblConfirm" runat="server" Text=""></asp:Label>
        </div>
    </form>
</body>
</html>

这里是Msft关于动态控件的一个起点,它解释了这种行为。这方面有很多资源。

http://msdn.microsoft.com/en-us/library/hbdfdyh7.aspx

专业提示:如果你能帮忙的话,不使用动态控件.虽然这可以说是支持不使用JavaScript的浏览器的一种不错的方法,但现在首选的方法是使用JavaScript动态构建控件并使用AJAX进行更新。否则,您发送的数据比您需要的要多。当您使用PostBack时,每次回发到服务器时,您都在(1)将整个ViewState加上表单数据上载到服务器,(2)重建整个页面(解析ViewState、呈现ViewState等等)。在服务器上,和(3)将所有的HTML (和ViewState)发送回客户机。这对于使用电力和数据计划费率的移动设备来说尤其麻烦。

票数 3
EN

Stack Overflow用户

发布于 2013-10-26 03:07:51

您需要将动态文本框的AutoPostback属性设置为True,以便它们触发TextChanged事件。

代码语言:javascript
运行
复制
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
    MyBase.OnInit(e)

    For i As Int16 = 0 To 5
        Dim txtTest As New TextBox
        txtTest.Text = "this is an OnInit generated textbox"
        txtTest.ID = "testOnInit" + i.ToString
        txtTest.AutoPostBack = True  
        Form.Controls.Add(txtTest)
        AddHandler txtTest.TextChanged, AddressOf txtTest_TextChanged
    Next
End Sub

Protected Sub txtTest_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
    Dim txt As TextBox = DirectCast(sender, TextBox)
    lblTest.Text = txt.ID & " value changed to " & txt.Text
End Sub
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19598141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档