Dynamically added button click event fire only once

Well, it may seem a repetitious and old problem, but I could not find any solution to it. I am writing a web application which has many forms all working fine with AJAX, except one. This form has two query panels and two parts for adding and editing items. One query panel is for searching through existing items and the other is for helping add/edit process. The entire form ASP.NET code is:

<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/Masters/Forms.Master" CodeBehind="EditBrands.aspx.vb" Inherits="PharmaManageWeb.EditBrands" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    <title>ویرایش برندها</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="PageContent" runat="server">
    <asp:ScriptManagerProxy runat="server" ID="PageScriptsProxy">
    </asp:ScriptManagerProxy>
    <asp:Table runat="server" CssClass="formtable">
        <asp:TableRow runat="server">
            <asp:TableCell runat="server">
                <asp:UpdatePanel runat="server" ID="AddPanel" UpdateMode="Conditional">
                    <ContentTemplate>
                        <asp:Table runat="server" ID="AddTable" CssClass="formtable">
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" ColumnSpan="2">
                                    افزودن برند:
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">
                                    نام:
                                </asp:TableCell>
                                <asp:TableCell runat="server">
                                    <asp:TextBox runat="server" ID="AddName" CssClass="rtlinput" Width="250px"></asp:TextBox>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">
                                    کد ژنریک:
                                </asp:TableCell>
                                <asp:TableCell runat="server">
                                    <asp:TextBox runat="server" ID="AddCode" CssClass="ltrinput" Width="100px"></asp:TextBox>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">
                                    نام ژنریک:
                                </asp:TableCell>
                                <asp:TableCell runat="server">
                                    <asp:TextBox runat="server" ID="AddGName" CssClass="ltrinput" Width="250px" Enabled="false"></asp:TextBox>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">&nbsp;</asp:TableCell>
                                <asp:TableCell runat="server">
                                    <asp:Label runat="server" ID="AddErrMsg" ForeColor="Red"></asp:Label>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">&nbsp;</asp:TableCell>
                                <asp:TableCell runat="server" CssClass="buttoncell">
                                    <asp:Button runat="server" ID="SubmitAdd" Text="ارسال" OnClick="DoAdd" />
                                </asp:TableCell>
                            </asp:TableRow>
                        </asp:Table>
                    </ContentTemplate>
                </asp:UpdatePanel>
                <br />
                <asp:UpdatePanel runat="server" ID="EditPanel" UpdateMode="Conditional">
                    <Triggers>
                        <asp:AsyncPostBackTrigger ControlID="SubmitAdd" EventName="Click" />
                    </Triggers>
                    <ContentTemplate>
                        <asp:Table runat="server" ID="EditTable" CssClass="formtable">
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" ColumnSpan="2">
                                    ویرایش برند:
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">
                                    نام:
                                </asp:TableCell>
                                <asp:TableCell runat="server">
                                    <asp:TextBox runat="server" ID="EditName" CssClass="rtlinput" Width="250px"></asp:TextBox>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">
                                    کد ژنریک:
                                </asp:TableCell>
                                <asp:TableCell runat="server">
                                    <asp:TextBox runat="server" ID="EditCode" CssClass="ltrinput" Width="100px"></asp:TextBox>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">
                                    نام ژنریک:
                                </asp:TableCell>
                                <asp:TableCell runat="server">
                                    <asp:TextBox runat="server" ID="EditGName" CssClass="ltrinput" Width="250px" Enabled="false"></asp:TextBox>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">&nbsp;</asp:TableCell>
                                <asp:TableCell runat="server">
                                    <asp:Label runat="server" ID="EditErrMsg" ForeColor="Red"></asp:Label>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server">&nbsp;</asp:TableCell>
                                <asp:TableCell runat="server" CssClass="buttoncell">
                                    <asp:Button runat="server" ID="SubmitEdit" Text="ارسال" OnClick="DoEdit" Enabled="false" />
                                </asp:TableCell>
                            </asp:TableRow>
                        </asp:Table>
                    </ContentTemplate>
                </asp:UpdatePanel>
                <br />
                <asp:UpdatePanel runat="server" ID="QueryPanel" UpdateMode="Conditional">
                    <ContentTemplate>
                        <asp:Table runat="server" ID="QueryTable" CssClass="formtable">
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" ColumnSpan="3">
                                    جستجوی برندها:
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" Width="20px">
                                    نام:
                                </asp:TableCell>
                                <asp:TableCell runat="server" Width="150px">
                                    <asp:TextBox runat="server" ID="QueryName" CssClass="rtlinput" Width="250px"></asp:TextBox>
                                </asp:TableCell>
                                <asp:TableCell runat="server" CssClass="buttoncell">
                                    <asp:Button runat="server" ID="SubmitQuery" Text="ارسال" OnClick="DoQuery" />
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" ColumnSpan="3">
                                    <asp:Label runat="server" ID="QueryErrMsg" ForeColor="Red"></asp:Label>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" ColumnSpan="3">
                                    <asp:Table runat="server" ID="QueryResults" CssClass="resulttable">
                                    </asp:Table>
                                </asp:TableCell>
                            </asp:TableRow>
                        </asp:Table>
                    </ContentTemplate>
                </asp:UpdatePanel>
            </asp:TableCell>
            <asp:TableCell runat="server">
                انتخاب کدهای ژنریک:<br />
                <br />
                <asp:UpdatePanel runat="server" ID="GQueryPanel" UpdateMode="Conditional">
                    <ContentTemplate>
                        <asp:Table runat="server" ID="GQueryTable" CssClass="formtable">
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" ColumnSpan="3">
                                جستجوی کدها:
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" Width="20px">
                                نام:
                                </asp:TableCell>
                                <asp:TableCell runat="server" Width="150px">
                                    <asp:TextBox runat="server" ID="GQueryName" CssClass="ltrinput" Width="250px"></asp:TextBox>
                                </asp:TableCell>
                                <asp:TableCell runat="server" CssClass="buttoncell">
                                    <asp:Button runat="server" ID="GSubmitQuery" Text="ارسال" OnClick="DoGQuery" />
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" ColumnSpan="3">
                                    <asp:Label runat="server" ID="GQueryErrMsg" ForeColor="Red"></asp:Label>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow runat="server">
                                <asp:TableCell runat="server" ColumnSpan="3">
                                    <asp:Table runat="server" ID="GQueryResults" CssClass="resulttable">
                                    </asp:Table>
                                </asp:TableCell>
                            </asp:TableRow>
                        </asp:Table>
                    </ContentTemplate>
                </asp:UpdatePanel>
            </asp:TableCell>
        </asp:TableRow>
    </asp:Table>
</asp:Content>

And the code behind:

Public Class EditBrands
    Inherits System.Web.UI.Page

    Private Sub Re_CreateQueryResults(ByVal dbc As SqlConnection)
        Dim qry As Base.Brands = Base.Brand.QueryBrands(dbc, Session("BrandQueryVal"))
        Dim i As Integer
        Dim tr As TableRow
        Dim tc As TableCell
        Dim bt As Button

        QueryResults.Rows.Clear()
        tr = New TableRow
        tc = New TableCell
        tc.Text = "شناسه"
        tc.CssClass = "resulttableordercol"
        tr.Cells.Add(tc)
        tc = New TableCell
        tc.Text = "نام"
        tc.CssClass = "resulttabledatacol"
        tr.Cells.Add(tc)
        tc = New TableCell
        tc.Text = "ویرایش"
        tc.CssClass = "resulttableordercol"
        tr.Cells.Add(tc)
        QueryResults.Rows.Add(tr)
        For i = 0 To qry.Count - 1
            tr = New TableRow
            tc = New TableCell
            tc.Text = qry(i).ID
            tc.CssClass = "resulttableordercol"
            tr.Cells.Add(tc)
            tc = New TableCell
            tc.Text = qry(i).Name
            tc.CssClass = "resulttabledatacol"
            tr.Cells.Add(tc)
            tc = New TableCell
            bt = New Button
            bt.Text = "ویرایش"
            bt.ID = "SubmitEdit" & qry(i).ID
            AddHandler bt.Click, AddressOf SubmitForEdit
            tc.Controls.Add(bt)
            tc.CssClass = "resulttableordercol"
            tr.Cells.Add(tc)
            QueryResults.Rows.Add(tr)
        Next
        If qry.Count = 0 Then
            QueryErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "NOTHINGFOUND")
            QueryResults.Rows.Clear()
        End If
    End Sub

    Private Sub Re_CreateGQueryResults(ByVal dbc As SqlConnection)
        Dim qry As StatBookManager.GenericNames = StatBookManager.GenericName.QueryGenericNames(dbc, Session("GenericQueryVal3"))
        Dim i As Integer
        Dim tr As TableRow
        Dim tc As TableCell
        Dim bt As Button

        GQueryResults.Rows.Clear()
        tr = New TableRow
        tc = New TableCell
        tc.Text = "کد"
        tc.CssClass = "resulttableordercol"
        tr.Cells.Add(tc)
        tc = New TableCell
        tc.Text = "نام"
        tc.CssClass = "resulttabledatacol"
        tr.Cells.Add(tc)
        tc = New TableCell
        tc.Text = "انتخاب برای"
        tc.ColumnSpan = 2
        tc.CssClass = "resulttableordercol"
        tr.Cells.Add(tc)
        GQueryResults.Rows.Add(tr)
        For i = 0 To qry.Count - 1
            tr = New TableRow
            tc = New TableCell
            tc.Text = qry(i).Code
            tc.CssClass = "resulttableordercol"
            tr.Cells.Add(tc)
            tc = New TableCell
            tc.Text = qry(i).Name
            tc.CssClass = "resulttabledatacolltr"
            tr.Cells.Add(tc)
            tc = New TableCell
            bt = New Button
            bt.Text = "افزودن"
            bt.ID = "SubmitForAdd" & qry(i).ID
            AddHandler bt.Click, AddressOf SubmitGForAdd
            ScriptManager.GetCurrent(Me.Page).RegisterAsyncPostBackControl(bt)
            tc.Controls.Add(bt)
            tc.CssClass = "resulttableordercol"
            tr.Cells.Add(tc)
            tc = New TableCell
            bt = New Button
            bt.Text = "ویرایش"
            bt.ID = "SubmitForEdit" & qry(i).ID
            AddHandler bt.Click, AddressOf SubmitGForEdit
            ScriptManager.GetCurrent(Me.Page).RegisterAsyncPostBackControl(bt)
            tc.Controls.Add(bt)
            tc.CssClass = "resulttableordercol"
            tr.Cells.Add(tc)
            GQueryResults.Rows.Add(tr)
        Next
        If qry.Count = 0 Then
            GQueryErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "NOTHINGFOUND")
            GQueryResults.Rows.Clear()
        Else
            GQueryErrMsg.Text = ""
        End If
    End Sub

    Protected Sub DoGQuery(ByVal sender As Object, ByVal e As EventArgs)
        Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))

        GQueryErrMsg.Text = ""
        If GQueryName.Text.Trim = "" Then
            GQueryErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "NOGENERICNAME")
            dbc.Close()
            Exit Sub
        End If

        Session("GenericQueryVal3") = GQueryName.Text
        Re_CreateGQueryResults(dbc)
        dbc.Close()
    End Sub

    Protected Sub SubmitGForAdd(ByVal sender As Object, ByVal e As EventArgs)
        MsgBox("A")
        Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))
        Dim itm As New StatBookManager.GenericName(dbc, Val(CType(sender, Button).ID.Substring(12)), StatBookManager.GenericName.IdentifyBy.ID)

        AddCode.Text = itm.Code
        AddGName.Text = itm.Name
        AddPanel.Update()
        dbc.Close()
    End Sub

    Protected Sub SubmitGForEdit(ByVal sender As Object, ByVal e As EventArgs)
        MsgBox("E")
        Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))
        Dim itm As New StatBookManager.GenericName(dbc, Val(CType(sender, Button).ID.Substring(13)), StatBookManager.GenericName.IdentifyBy.ID)

        EditCode.Text = itm.Code
        EditGName.Text = itm.Name
        EditPanel.Update()
        dbc.Close()
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
            If Session("GenericQueryVal3") IsNot Nothing Then
                Session.Remove("GenericQueryVal3")
                Exit Sub
            End If
        End If

        Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))

        If Page.IsPostBack AndAlso (Session("BrandQueryVal") IsNot Nothing) AndAlso (AJAXUtils.GetAsyncPostBackControlID(Me.Page).EndsWith("$QueryPanel")) Then
            Re_CreateQueryResults(dbc)
            If QueryName.Text = "" Then QueryName.Text = Session("BrandQueryVal")
        End If
        If Page.IsPostBack AndAlso (Session("GenericQueryVal3") IsNot Nothing) AndAlso (AJAXUtils.GetAsyncPostBackControlID(Me.Page).EndsWith("$GQueryPanel")) Then
            Re_CreateGQueryResults(dbc)
            If GQueryName.Text = "" Then GQueryName.Text = Session("GenericQueryVal3")
        End If
        dbc.Close()
    End Sub

    Protected Sub DoAdd(ByVal sender As Object, ByVal e As EventArgs)
        Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))

        AddErrMsg.Text = ""
        If AddName.Text.Trim = "" Then
            AddErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "NOBRANDNAME")
            dbc.Close()
            Exit Sub
        End If
        If AddCode.Text.Trim = "" Then
            AddErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "NOGENERICCODE")
            dbc.Close()
            Exit Sub
        End If

        Dim itm As New Base.Brand

        If Not itm.GenericName.Load(dbc, Val(AddCode.Text), StatBookManager.GenericName.IdentifyBy.Code) Then
            AddErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "GENERICNOTFOUND")
            dbc.Close()
            Exit Sub
        End If

        itm.Name = AddName.Text
        itm.Register(dbc)
        AddName.Text = ""
        AddCode.Text = ""
        AddGName.Text = ""
        EditName.Text = ""
        EditCode.Text = ""
        EditGName.Text = ""
        SubmitEdit.Enabled = False
        dbc.Close()
    End Sub

    Protected Sub DoEdit(ByVal sender As Object, ByVal e As EventArgs)
        Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))
        Dim itm As New Base.Brand(dbc, Session("BrandEditID"))

        EditErrMsg.Text = ""
        If EditName.Text.Trim = "" Then
            EditErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "NOBRANDNAME")
            dbc.Close()
            Exit Sub
        End If
        If EditCode.Text.Trim = "" Then
            EditErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "NOGENERICCODE")
            dbc.Close()
            Exit Sub
        End If
        If Not itm.GenericName.Load(dbc, Val(EditCode.Text), StatBookManager.GenericName.IdentifyBy.Code) Then
            EditErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "GENERICNOTFOUND")
            dbc.Close()
            Exit Sub
        End If

        itm.Name = EditName.Text
        itm.Save(dbc)
        EditName.Text = ""
        EditCode.Text = ""
        EditGName.Text = ""
        SubmitEdit.Enabled = False
        Re_CreateQueryResults(dbc)
        QueryPanel.Update()
        dbc.Close()
    End Sub

    Protected Sub DoQuery(ByVal sender As Object, ByVal e As EventArgs)
        Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))

        QueryErrMsg.Text = ""
        If QueryName.Text.Trim = "" Then
            QueryErrMsg.Text = SystemSys.SysMan.GetSystemMessage(dbc, "NOBRANDNAME")
            dbc.Close()
            Exit Sub
        End If

        Session("BrandQueryVal") = QueryName.Text
        Re_CreateQueryResults(dbc)
        dbc.Close()
    End Sub

    Protected Sub SubmitForEdit(ByVal sender As Object, ByVal e As EventArgs)
        Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))
        Dim itm As New Base.Brand(dbc, Val(CType(sender, Button).ID.Substring(10)))

        Session("BrandEditID") = itm.ID
        EditName.Text = itm.Name
        EditCode.Text = itm.GenericName.Code
        EditGName.Text = itm.GenericName.Name
        SubmitEdit.Enabled = True
        EditPanel.Update()
        Re_CreateQueryResults(dbc)
        dbc.Close()
    End Sub

    Private Sub EditBrands_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
        If Page.IsPostBack AndAlso (Session("GenericQueryVal3") IsNot Nothing) Then
            Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))

            Re_CreateGQueryResults(dbc)
            dbc.Close()
        End If
    End Sub
End Class

Dynamic add/edit buttons are added in Re_CreateGQueryResults() subroutine. As you see, I have added two MsgBox statements saying "A" when a dynamic add button is clicked, and "E" when a dynamic edit button is clicked. The problem is exactly here: when I click on a dynamic add button, MsgBox("A") works, but only for the first! Further clicks don't result in any further message boxes (and not in any change in contents of AddName, AddCode, AddGName), and other dynamic edit buttons don't work as well until session expiration (say, with a rebuild on ASP.NET Development Server). A similar behavior happens with first click on dynamic edit buttons (No further message boxes, neither by edit buttons nor add buttons).

Where is the problem?

EDIT:

I solved this problem by both moving page load code to page init event and adding AsyncPostBackTriggers for every dynamic add and edit button to GQueryPanel's Triggers collection (Although Microsoft explicitly says that this wouldn't work; but worked for me!). Now, there is another problem: SubmitGForAdd() and SubmitGForEdit() subroutines don't work as expected. Before this, on first click, AddCode and AddGName textboxes were taking their values and these values were displaying on browser. But now, they are always empty. I tested if code runs and itm variable loads it's data correctly. I believe these textboxes take their values, but they vanish on the way to browser! Can anyone explain why?


ANSWERS:


I solved this problem by both moving page load code to page init event and adding AsyncPostBackTriggers for every dynamic add and edit button to GQueryPanel's Triggers collection (Although Microsoft explicitly says that this wouldn't work; but worked for me!). This is the exact code differences:

In: Re_CreateGQueryResults()

...
        Dim trg as AsyncPostBackTrigger
...
        For i = 0 To qry.Count - 1
...
            AddHandler bt.Click, AddressOf SubmitGForAdd
            trg = New AsyncPostBackTrigger
            trg.ControlID = bt.ID
            trg.EventName = "Click"
            GQueryPanel.Triggers.Add(trg)
...
            AddHandler bt.Click, AddressOf SubmitGForEdit
            trg = New AsyncPostBackTrigger
            trg.ControlID = bt.ID
            trg.EventName = "Click"
            GQueryPanel.Triggers.Add(trg)
...

And:

Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
    If Not Page.IsPostBack Then
        If Session("GenericQueryVal3") IsNot Nothing Then
            Session.Remove("GenericQueryVal3")
            Exit Sub
        End If
    End If

    Dim dbc As SqlConnection = Connectivity.GetConnectionToDB(Session("DatabaseName"))

    If Page.IsPostBack AndAlso (Session("BrandQueryVal") IsNot Nothing) AndAlso (AJAXUtils.GetAsyncPostBackControlID(Me.Page).EndsWith("$QueryPanel")) Then
        Re_CreateQueryResults(dbc)
        If QueryName.Text = "" Then QueryName.Text = Session("BrandQueryVal")
    End If
    If Page.IsPostBack AndAlso (Session("GenericQueryVal3") IsNot Nothing) AndAlso (AJAXUtils.GetAsyncPostBackControlID(Me.Page).EndsWith("$GQueryPanel")) Then
        Re_CreateGQueryResults(dbc)
        If GQueryName.Text = "" Then GQueryName.Text = Session("GenericQueryVal3")
    End If
    dbc.Close()
End Sub

Regards



 MORE:


 ? Dynamic Button Click in Table
 ? Create onClick event for dynamically created button asp.net
 ? Dynamically Add Click event to asp button
 ? Dynamically Add Click event to asp button
 ? Dynamically Add Click event to asp button
 ? Button Click Event Getting Lost
 ? Dynamically assign button events in c# asp.net
 ? how to create an asp button dynamically and add event to it
 ? C# how to handle multiple button click events?
 ? C# Add Controls To Panel In a Loop