Blunderfest
Blunderfest

Reputation: 1854

Dynamically created buttons not calling function on postback

In my visual basic web application I have a list of generated buttons that are supposed to allow the download of a file on click.

I had the example working with generated buttons on pageload, but all of a sudden the download function stopped getting called on post back, and now all the button click does (for any of the buttons) is cause a page post back.

My code:

Public folder As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not IsPostBack Then
        folder = "Main"
        PopulateFiles(folder)
    End If
End Sub

Protected Sub PopulateFiles(ByVal folder As String)
    Dim myConnection As SqlConnection
    Dim conString As String = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
    Dim myCommand As SqlCommand
    Dim myDataReader As SqlDataReader
    Dim text As String
    Dim size As Decimal
    Dim name As String
    Dim type As String
    Dim id As Integer
    folderName.Text = folder
    container.Controls.Clear()
    myConnection = New SqlConnection(conString)
    myConnection.Open()
    myCommand = New SqlCommand("Uploads_GetAllFiles", myConnection)
    myCommand.CommandType = CommandType.StoredProcedure
    myCommand.Parameters.AddWithValue("@folder", folder)
    Try
        myDataReader = myCommand.ExecuteReader()
        If myDataReader.HasRows Then
            Do While myDataReader.Read()
                name = myDataReader.Item("Name")
                type = myDataReader.Item("Type")
                id = myDataReader.Item("File_ID")
                size = Math.Round(myDataReader.Item("Size") / 1000, 2)
                container.Controls.Add(New LiteralControl("<div class='newRow'>"))
                text = "<div class='fileName'>" & name & "</div>"
                container.Controls.Add(New LiteralControl(text))
                text = "<div class='fileType'>" & type & "</div>"
                container.Controls.Add(New LiteralControl(text))
                text = "<div class='fileSize'>" & size.ToString() & "kb</div>"
                container.Controls.Add(New LiteralControl(text))
                container.Controls.Add(New LiteralControl("<div class='fileDownload'>"))
                Dim newBtn As New Button
                newBtn.ID = "link" & id
                newBtn.Text = "Download"
                newBtn.CssClass = "newbie"
                AddHandler newBtn.Click, AddressOf Retreive_Doc
                newBtn.CommandArgument = id
                container.Controls.Add(newBtn)
                container.Controls.Add(New LiteralControl("</div>"))
                container.Controls.Add(New LiteralControl("<div class='fileDelete'>"))
                Dim newDelBtn As New Button
                newDelBtn.ID = "delete" & id
                newDelBtn.Text = "Delete"
                newDelBtn.CssClass = "delBtn"
                AddHandler newDelBtn.Click, AddressOf Retreive_Xls
                newDelBtn.CommandArgument = id
                container.Controls.Add(newDelBtn)
                container.Controls.Add(New LiteralControl("</div>"))
                container.Controls.Add(New LiteralControl("</div>"))
            Loop
        End If

    Catch ex As Exception
        MsgBox(ex.ToString())
    Finally
        myConnection.Close()
    End Try
End Sub

Protected Sub Retreive_Doc(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
    Dim button As Button = sender
    Dim id As Integer = button.CommandArgument
    Dim cmd As SqlCommand = New SqlCommand("Uploads_GetFile")
    cmd.CommandType = CommandType.StoredProcedure
    cmd.Parameters.AddWithValue("@id", id)
    Dim dt As DataTable = GetData(cmd)
    If dt IsNot Nothing Then
        download(dt)
    End If
End Sub

I could show the functions called from this function, but the initial function isn't even being called so I'm not sure there is a point.

My HTML is as follows:

<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:FileUpload ID="upload1" runat="server" /><asp:Button ID="test1" runat="server" Text="Upload" />
<asp:TextBox ID="folderTag" runat="server" ></asp:TextBox>
<asp:Button ID="search" runat="server" Text="Search" />
<asp:Label ID="folderName" runat="server">General</asp:Label><br />
<div id="navContainer" runat="server">

</div>
    <div id="hiddenContent">      
    <asp:LinkButton ID="LinkButton1" CssClass="hide" runat="server" OnClick = "Retreive_Doc">Download Doc</asp:LinkButton>
    <asp:LinkButton ID="LinkButton2" CssClass="hide" runat="server" OnClick = "Retreive_Xls">Download xls</asp:LinkButton>
    </div>
<div id="container" runat="server">
</div>
</form>

As I said before. This was working a few days ago and through the course of adding some other functionality somehow I lost it.

I'm unsure of why it posts back without calling any function.

Thanks for any help!

Upvotes: 0

Views: 983

Answers (1)

Win
Win

Reputation: 62290

You need to recreate the controls with same ID in post back if you created them dynamically. Otherwise, they will disappear after postback.

Remove If Not IsPostBack Then in page load event.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) 
  Handles Me.Load
   folder = "Main"
   PopulateFiles(folder)
End Sub

Another thought:

Is there a reason not to use CommandEvent instead of Click event if you want CommandArgument?

Again, Is there a reason not to use PlaceHolder instead of <div id="container" runat="server">?

AddHandler newBtn.Command, AddressOf Retreive_Doc
newBtn.CommandArgument = id

....

protected void Retreive_Doc(object sender, CommandEventArgs e)

Upvotes: 1

Related Questions