簡體   English   中英

動態事件處理程序不會觸發

[英]Dynamic Event Handler not Firing

我想根據用戶輸入文本框的數字動態創建一定數量的控件。 這部分我工作正常,但我還需要動態創建的文本框來擁有自己的事件處理程序,因此用戶可以在其中輸入數字,並創建更多控件。

我的問題是我為這些控件設置的事件處理程序不會觸發。 也許我沒有正確理解ASP.NET頁面生命周期,但我目前正在OnInit事件中生成動態控件(在我在第一個文本框的TextChanged事件中生成它們之前,但切換到使用OnInit基於Oded的建議的事件我在這里找到: 動態添加的事件處理程序不會被觸發 )。

編輯

我刪除了我最初發布的代碼,因為這篇帖子太長了。

我將發布我的整個.aspx代碼和這里的代碼,所以你們知道這正是我正在看的。 同樣,當文本在其中更改時,由此代碼生成的動態TextBox不會觸發綁定到它的事件處理程序,它只會消失。 有趣的是 - 我認為當您更改文本時實際上會發生回發,但它不會觸發事件處理程序...

ASPX前端:

<%@ 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

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從頁面中消失...再次感謝您幫忙!

由於ViewState動態控件可能有點棘手

基本上:您正在添加動態控件以響應TextChanged事件,該事件在InitLoad之后以及反序列化ViewState之后觸發。 因此,您遇到了問題,因為ViewState不知道動態控件並且與您的期望不一致。 通過在Load階段檢查txtEnter.Text的值並在那里創建控件,您可以讓ViewState知道控件(記住, dynamicEventHandler頁面加載時都會創建控件!),因此dynamicEventHandler現在有一個上下文從哪個執行。

這是更正的代碼(但為了簡單起見,作為帶有嵌入式VB的單個文件,您當然可以將其分離為代碼隱藏文件):

<%@ 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 PLUS上傳表單數據到服務器,(2)重建整個頁面(解析ViewState ,呈現HTML等)服務器,以及(3)將所有HTML(和ViewState )發送回客戶端。 對於適用電源和數據計划費率的移動設備而言,這尤其麻煩。

您需要將動態文本框的AutoPostback屬性設置為True以便它們觸發TextChanged事件。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM