3

Я хочу создать количество элементов управления динамически на основе числа, которое пользователь вводит в текстовое поле. В этой части я отлично работаю, но мне также нужны динамически созданные текстовые поля для собственных обработчиков событий, поэтому пользователь может ввести число в них и создать больше элементов управления.Динамический обработчик событий не запускается

Моя проблема в том, что обработчик событий я установки для этих элементов управления использовать не срабатывает. Возможно, я не правильно понял жизненный цикл страницы ASP.NET, но в настоящее время у меня есть динамические элементы управления, созданные внутри события OnInit (до того, как я генерировал их внутри события TextChanged самого первого текстового поля, но переключился на использование OnInit событие, основанное на совете от Одеда, я нашел здесь: Dynamically Added Event Handler Not Firing).

EDIT

Я удалил код, который я первоначально отправил, потому что этот пост будет просто слишком долго иначе.

Я собираюсь отправить весь свой код .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 Inherits 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 исчезает со страницы ... Спасибо снова за помощь!

+0

Этот код должен работать нормально. Вы уверены, что цикл повторяется и что вы выполняете какое-либо изменение (и проверяете его) в соответствующих текстовых окнах? – varocarbas

+0

Да, я прошел через цикл, прошел, генерирует текстовые поля, но когда я меняю текст в любом из этих текстовых полей, их событие textChanged (которое является событием выше в моем коде) не срабатывает. Динамические текстовые поля отображаются на странице ... это просто, что их обработчики событий не срабатывают. –

+0

Помните, что в ASP поведение отличается от Winforms. Это событие запускается только при отправке изменений на сервер (http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.textbox.textchanged.aspx), то есть, когда например, нажмите «ввод». – varocarbas

ответ

3

Динамические элементы управления могут быть немного сложнее из-за ViewState

В принципе: вы добавления динамических элементов управления в ответ на TextChanged событие, которое выстреливает после Init и Load и после ViewState был десериализации. Поэтому вы столкнулись с проблемой, потому что ViewState не знал о динамических элементах управления и не соответствовал вашим ожиданиям. Проверяя значение txtEnter.Text на фазе Load и создавая элементы управления там, вы можете сделать свой ViewState информацией об элементах управления (которые, помните, создаются КАЖДОЕ время загрузки страницы!), И поэтому ваш dynamicEventHandler10 теперь имеет контекст, из которого выполнить.

Вот исправленный код (но как единый файл со встроенным 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

Pro-наконечник: не использовать динамические элементы управления, если вы можете помочь ему. Хотя это, возможно, достойный способ поддержки браузеров, которые не используют JavaScript, в наши дни предпочтительным подходом является динамическое создание элементов управления с помощью JavaScript и использование AJAX для обновления. В противном случае вы отправляете больше данных, чем вам нужно. Когда вы используете PostBack, каждый раз, когда вы отправляете POST на сервер, вы (1) загружаете всю информацию о форме на сервер, (2) восстанавливаете всю страницу (разбор ViewState, отрисовка HTML и т. Д.) На сервер и (3) отправить все HTML (и ViewState) обратно клиенту. Это особенно неприятно для мобильных устройств, в которых применяются энергопотребление и тарифы на передачу данных.

+0

Спасибо за предложение. Это то, что я делал до того, как начал использовать OnInit, но он все еще не работает. Что странно, я попытался заменить динамическое текстовое поле динамической кнопкой, и когда я нажимаю динамически добавленную кнопку, обработчик событий, который я добавил для него, не срабатывает, но кнопка исчезает ... Я в замешательстве. –

+0

Можете ли вы опубликовать полный код? также - думая, что вам может быть повезло с этим с помощью регулятора 'Repeater' и с помощью обработчика' ItemCommand' – nothingisnecessary

+0

. Раньше я никогда не использовал элемент Repeater, но об этом узнаю сегодня утром. Проблемы, которые у меня возникают, изначально размещенные в этом потоке, все равно вытаскивают из меня дерьмо: \. –

1

Вам нужно будет установить свойство динамических текстовых полей 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 
+0

Большое спасибо за указание на это! Установка свойства AutoPostBack в True позволяет txtTest отвечать на измененный текст. Я понятия не имею, как я забыл об этом! Однако, так же, как когда я использовал кнопку вместо текстового поля, когда я меняю текст, динамически созданный элемент управления (будь то кнопка или текстовое поле) просто исчезает. Он не запускает назначенный ему обработчик событий (я установил разрыв point to confirm - обработчик событий не был выполнен). –

+0

Мне интересно - обработчики событий для элементов управления, которые не генерируются динамически, имеют «дескрипторы » в конце определения их метода. Все примеры, которые я видел в динамических элементах управления/обработчиках событий, показывают, что эта часть отсутствует. Очевидно, что событие не знает, какой контроль он обрабатывает, если элемент управления еще не существует, поэтому, если вы попытаетесь его определить, .NET увидит это и не позволит программе работать. Должен ли я объявлять метод обработчика событий по-разному? –

Смежные вопросы