ASP.NET динамическое событие кнопки команды не срабатывает



Я пытаюсь динамически создавать командные кнопки, но щелчок по соответствующей кнопке не вызывает соответствующего события CommandButton_Click. Я заметил, что в примерах на SO свойство установлено для Button.OnCommand, а также CommandName и CommandArgument, но это не опция в intellisense.

Итак, вопрос в том, что я делаю неправильно здесь (код ниже без OnCommand), доступен ли он каким-то другим способом - если да, то почему примеры, которые я нашел все покажите это как .По OnCommand?

EDIT: Далее, чтобы помочь, я добавил обработчик, однако событие все еще не запускается. Кнопки находятся в панели UpdatePanel и перестраиваются при каждой обратной передаче (вместе с обработчиком). Я создал упрощенный пример того, что я делаю, который показан ниже, Если событие кнопки срабатывает, оно записывает "событие сработало" в текстовое поле txtTestFired - достаточно сказать, что я никогда этого не видел. Это действительно сводит меня с ума, любая помощь очень благодарна полученный.

.aspx файл

<form id="frmMain" runat="server">
    <asp:ScriptManager ID="scmAddProducts" runat="server">
    </asp:ScriptManager>
    <asp:updatepanel runat="server">
        <ContentTemplate>
            <asp:TextBox ID="txtProduct" runat="server"></asp:TextBox>
            <br />
            <asp:Button ID="btnAddItem" runat="server" Text="Add Line" />&nbsp;
            <asp:TextBox ID="txtTestFired" runat="server"></asp:TextBox>
            <br />
            <br />
            <asp:Panel ID="pnlAddedLines" runat="server"></asp:Panel>
        </ContentTemplate>
    </asp:updatepanel>
</form>

.аспн.VB файл

Protected Sub btnAddItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddItem.Click
    Dim dtItems As New System.Data.DataTable

    If Session("Items") Is Nothing Then
        Dim dcColumn As New System.Data.DataColumn
        dcColumn.DataType = Type.GetType("System.String")
        dcColumn.ColumnName = "Product"
        dtItems.Columns.Add(dcColumn)
        Session("Items") = dtItems
    End If

    dtItems = CType(Session("Items"), System.Data.DataTable)
    Dim drRow As System.Data.DataRow
    drRow = dtItems.NewRow()
    drRow("Product") = txtProduct.Text
    dtItems.Rows.Add(drRow)

    Session("Items") = dtItems
    txtProduct.Text = ""
End Sub
Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
    If Not Session("Items") Is Nothing Then
        Dim dtItems As System.Data.DataTable = CType(Session("Items"), System.Data.DataTable)
        Dim iItemIndex As Integer = 1
        For Each drRow In dtItems.Rows
            Dim btnClose As New Button
            btnClose.ID = "btnClose" & iItemIndex
            btnClose.CssClass = "formCloseButton"
            btnClose.Text = "X"
            AddHandler btnClose.Click, AddressOf Button_Clicked
            pnlAddedLines.Controls.Add(btnClose)
            btnClose = Nothing

            Dim txtProduct = New TextBox
            txtProduct.ID = "txtProduct" & iItemIndex
            txtProduct.CssClass = "formText"
            txtProduct.Text = drRow("Product")
            txtProduct.Columns = "40"
            pnlAddedLines.Controls.Add(txtProduct)
            iItemIndex += 1

            Dim litHR = New Literal
            litHR.Text = "<hr />"
            pnlAddedLines.Controls.Add(litHR)
            litHR = Nothing
        Next
    End If
End Sub
Private Sub Button_Clicked(ByVal sender As Object, ByVal e As System.EventArgs)
    txtTestFired.Text = "EVENT FIRED"
End Sub
132   5  

5 ответов:

По существу, вам нужно создать исходные элементы управления сразу после загрузки страницы, чтобы иметь возможность обрабатывать щелчок кнопки, затем вам нужно очистить элементы управления и повторно сгенерировать их либо в обработчике щелчка кнопки, либо так, как вы это сделали на pre-render - я думаю, что это чище на обработчике щелчка, поэтому вам нужен один и тот же код в обоих (предпочтительно рефакторинг до отдельного метода)

Приведенный ниже пример будет означать минимальные изменения кода для вас:

Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
    If Not Session("Items") Is Nothing Then
        pnlAddedLines.Controls.Clear()
        GenerateControls()
    End If
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Session("Items") Is Nothing Then
        GenerateControls()
    End If
End Sub
Private Sub GenerateControls()
    Dim dtItems As System.Data.DataTable = CType(Session("Items"), System.Data.DataTable)
    Dim iItemIndex As Integer = 1
    For Each drRow In dtItems.Rows
        Dim btnClose As New Button
        btnClose.ID = "btnClose" & iItemIndex

Вы должны подключить его вот так (в C#):

myButton.Click += new EventHandler(this.Button_Clicked);

Альтернативно можно ввести атрибут -- > onclick = "Button_Clicked" следующим образом:

myButton.Attributes.Add("onclick", "Button_Clicked");

Если вы хотите, чтобы он вошел VB.NET зайдите на эту страницу и вырубитесь - я мог бы сделать это за вас, но в чем смысл :)

EDIT : имейте в виду, что вам придется повторно подключать обработчик событий (как показано выше) при каждой загрузке страницы.

EDIT : OK - теперь, когда вы добавили остальную часть кода, я вижу проблему. Вы подключаетесь к сети обработчик событий на pre_render. Обработчики событий выполняются непосредственно перед load_complete, что происходит до pre_render. Вот почему event_handler не выполняется: вы добавляете его слишком поздно в жизненном цикле страницы . Поместите этот код в процедуру page_load, и он должен работать.

У меня была та же проблема, я загружал элементы управления просто отлично. события разворачивались в первый раз, но не во второй. Проблема заключалась в том, что у меня не было уникального идентификатора, привязанного к элементам управления. Поэтому я добавил уникальное поле ID к элементу управления, который я добавлял на страницу, и он работал просто отлично, каждый клик.

Вам нужно подключить событие click. Смотрите этот код...

Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim button1 As New Button
        Dim button2 As New Button

        button1.ID = "button1"
        button1.Text = "Button 1"
        button2.ID = "button2"
        button2.Text = "Button 2"

        AddHandler button1.Click, AddressOf OnClick
        AddHandler button2.Click, AddressOf OnClick

        form1.Controls.Add(button1)
        form1.Controls.Add(button2)

    End Sub

    Private Sub OnClick(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim buttonId As String

        buttonId = DirectCast(sender, Button).ID

        Response.Write("Button clicked: " + buttonId)

    End Sub

End Class

Надеюсь, это поможет...

Правильный путь:

  1. OnLoad-генерация динамического контента (создание динамических кнопок)
  2. кнопка OnClick-потребляет событие и восстанавливает правильное содержимое

Но это требует, чтобы генерировать контент дважды-один раз для создания кнопок для обработки событий, а затем стереть старый контент и генерировать правильный один - второй раз. Вы можете обойти его следующим образом:

  1. OnLoad-проверить, был ли нажат buton
  2. пререндер - создание правильного контента с динамическими кнопками (контент генерируется только один раз)

Мой пример для этого:

<script type="text/javascript" language="javascript">
    function SetPostBackAction(Action,ReturnValue)
    {
        if(ReturnValue)
            document.getElementById('<%=hfPostBackAction.ClientID%>').value=Action;
        return ReturnValue;
    }
</script>
<asp:HiddenField ID="hfPostBackAction" EnableViewState="false" runat="server" />

И в коде:

protected void Page_PreRender(object sender, EventArgs e)
{
    //Dynamic button in PreRender
    System.Web.UI.WebControls.Button btn=new System.Web.UI.WebControls.Button()
    btn.ID=string.Format("DeleteButton_SomeData{0}", 12345);
    btn.Text="Delete";
    btn.OnClientClick=string.Format("return SetPostBackAction('DeleteButton_SomeData{0}',window.confirm('Are you sure to delete?'))", 12345);
    btn.Click+=new EventHandler(btnDelete_Click);//This method will not be called if button is created in PreRender
}

protected void Page_Load(object sender, EventArgs e)
{
    //Do something...
    //Check Action
    ProccessAction();//You can check action whereever you want
}

protected void ProccessAction()
{
    string Action=Request.Form[hfPostBackAction.UniqueID]??string.Empty;
    int SomeData;

    if(Action.StartsWith("DeleteButton_"))//Is action?
    {
        SomeData=int.Parse(Action.Substring("DeleteButton_SomeData".Length));
        //Do something...
    }
    //Erase Action field not to fire action next time accidentially
    hfPostBackAction.Value=string.Empty;
}
    Ничего не найдено.

Добавить ответ:
Отменить.