Dynamically Added Event Handler Not Firing in VB.NET - asp.net

For some reason when I click the "Remove" button nothing happens. I'm assuming that this has something to do with view state and losing the handlers on page load, though I still can't make sense of it. I'm recreating the handler every time the page loads, why isn't this working?
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
If IsPostBack Then
If Not IsNothing(fileUpload.PostedFile) AndAlso fileUpload.PostedFile.ContentLength > 0 Then
_files = TryCast(Session("FilesToSend"), List(Of document))
_files.Add(New Document(fileUpload.FileName, fileUpload.FileBytes, fileUpload.FileBytes.Length))
loadTable()
End If
Else
Session("FilesToSend") = New List(Of document)
End If
End Sub
Private Sub loadTable()
Dim count As Integer = 0
For Each doc In _files
Dim r As New TableRow()
'Add Filename Cell
Dim filenameCell As New TableCell()
filenameCell.Text = doc.filename
r.Cells.Add(filenameCell)
'Add Size Cell
Dim sizeCell As New TableCell()
sizeCell.Text = doc.fileSize
r.Cells.Add(filenameCell)
'Add Remove Button Cell
Dim deleteButton As New Button
Dim deleteCell As New TableCell()
With deleteButton
.Text = "Remove"
'.ID = "deleteButton" + count.ToString()
deleteCell.Controls.Add(deleteButton)
AddHandler deleteButton.Click, AddressOf deleteRow_Click
End With
r.Cells.Add(deleteCell)
'AddHandler deleteButton.Click, New EventHandler(AddressOf deleteRow_Click)
'Add Row to Table
uploadedDocumentsTable.Rows.Add(r)
count += 1
Next
End Sub
Protected Sub deleteRow_Click(sender As Object, e As System.EventArgs)
_files = TryCast(Session("FilesToSend"), List(Of Document))
Dim deleteButton = TryCast(sender, Button)
_files.RemoveAt(sender.ID)
loadTable()
End Sub

Well after some more trial and error I finally figured it out. So the first issue was that I needed to add ".CausesValidation = False". This triggered the Postback, but then I needed to do some rearranging to make sure the controls were still getting loaded. Here's what worked:
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
If IsPostBack Then
_files = TryCast(Session("FilesToSend"), List(Of Document))
If Not IsNothing(fileUpload.PostedFile) AndAlso fileUpload.PostedFile.ContentLength > 0 Then
_files.Add(New Document(fileUpload.FileName, fileUpload.FileBytes, fileUpload.FileBytes.Length))
End If
Else
Session("FilesToSend") = New List(Of document)
End If
loadTable()
End Sub
Private Sub loadTable()
uploadedDocumentsTable.Rows.Clear()
Dim count As Integer = 0
For Each doc In _files
Dim r As New TableRow()
'Add Filename Cell
Dim filenameCell As New TableCell()
filenameCell.Text = doc.filename
r.Cells.Add(filenameCell)
'Add Size Cell
Dim sizeCell As New TableCell()
sizeCell.Text = doc.fileSize
r.Cells.Add(filenameCell)
'Add Remove Button Cell
Dim deleteButton As New Button
Dim deleteCell As New TableCell()
With deleteButton
.Text = "Remove"
.CausesValidation = False
.ID = count.ToString()
deleteCell.Controls.Add(deleteButton)
AddHandler deleteButton.Click, AddressOf deleteRow_Click
End With
r.Cells.Add(deleteCell)
'Add Row to Table
uploadedDocumentsTable.Rows.Add(r)
count += 1
Next
End Sub
Protected Sub deleteRow_Click(sender As Object, e As System.EventArgs)
_files.RemoveAt(sender.ID)
loadTable()
End Sub

You forgot to add the button to the Form. Modify it this way:
'Add Remove Button Cell
Dim deleteButton As New Button
Dim deleteCell As New TableCell()
With deleteButton
.Text = "Remove"
'.ID = "deleteButton" + count.ToString()
deleteCell.Controls.Add(deleteButton)
AddHandler deleteButton.Click, AddressOf deleteRow_Click
End With
Me.Controls.Add(deleteButton)
Surprise, you button is now located at position (0, 0), and the event is now listened to. You may want to modify it's position too, I guess.
Have fun!

Related

How to add linkbutton control to table cell dynamically

how to add linkbutton control to table cell dynamically and its event handler .?
Class SurroundingClass
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
Dim tbl As HtmlTable = New HtmlTable()
Dim tr As HtmlTableRow = New HtmlTableRow()
Dim td As HtmlTableCell = New HtmlTableCell()
tr.Cells.Add(td)
tbl.Rows.Add(tr)
Dim lbtn As LinkButton = New LinkButton()
lbtn.Text = "My Link Button"
lbtn.Click += New EventHandler(AddressOf LinkButton1_Click) '<- THIS LINE ERROR
td.Controls.Add(lbtn)
End Sub
Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As EventArgs)
End Sub
End Class
ERROR message image
Ah, you are using the C# format for attaching the event "+=", in VB use the AddHandler method.
For Example:
AddHandler lbtn.Click, AddressOf LinkButton1_Click

How to load database content to dynamic TextBox when an item is selected from dynamic DropDownList?

This is my interface, all the asp elements displayed are dynamically created! (Except the header)
Things I perform dynamically:
1. Create row with all those asp elements when page loads or button clicked.
2. I am able to lo populate DropDownList in "Items" column from database when it is created dynamically.
What I want to achieve?:
I want to load 'item code' 'item price' to appropriate text box when the item is selected from the DropDownList.
(Ex: when I click Laptop; it should load its item code and unit price to appropriate text box)
(Sorry for my bad programming approach, I'm beginner to asp.net)
'Page Load function'
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack or Page.IsPostBack Then
GenerateRows(numRows) 'Creates dynamic Table row and column with TextBox and DropDownList'
End If
End Sub
'Dynamic generating function, i have trimmed the code, to make it simple'
Protected Sub GenerateRows(numRows As Integer)
For i = 0 To numRows
Dim tRow As New TableRow
Dim tCode As New TableCell
Dim tItem As New TableCell
Dim lCode As New TextBox
Dim dList As New DropDownList
con = New Data.SqlClient.SqlConnection("Data Source=(localdb)\Projects;Initial Catalog=DataStore;Integrated Security=True")
con.Open()
query = "Select Item_Desc from Product"
cmd = New Data.SqlClient.SqlCommand(query, con)
cmd.ExecuteNonQuery()
dList.DataSource = cmd.ExecuteReader
dList.DataTextField = "Item_Desc"
dList.DataBind()
dList.Items.Insert(0, New ListItem("--- Select Product ---"))
dList.Height = 30
dList.AutoPostBack = True
dList.CausesValidation = True
AddHandler dList.SelectedIndexChanged, AddressOf Dynamic_Method
con.Close()
tCode.Controls.Add(lCode)
tItem.Controls.Add(dList)
tRow.Cells.Add(tCode)
tRow.Cells.Add(tItem)
Table1.Rows.Add(tRow) 'Table1 is not dynamic element'
Next
numRows += 1
ViewState("RowCount") = numRows 'numRows is Global variable'
End Sub
'This function is called when the selected index of DropDownList changes'
Protected Sub Dynamic_Method(ByVal sender As Object, ByVal e As EventArgs)
con = New Data.SqlClient.SqlConnection("Data Source=(localdb)\Projects;Initial Catalog=DataStore;Integrated Security=True")
con.Open()
Dim DDL As DropDownList = DirectCast(sender, DropDownList)
query = "Select * from Product where Item_Desc='" & DDL.SelectedValue.ToString & "'"
cmd = New Data.SqlClient.SqlCommand(query, con)
cmd.ExecuteNonQuery()
dr = cmd.ExecuteReader
If dr.HasRows = True Then
While (dr.Read)
ic = dr(0) 'dr(0) contains Item code of selected value which i need to add to textbox'
End While
End If
con.Close()
End Sub

ASP VB Stuck on Dynamic Controls, Viewstate, and Postback. Could really use some help to get back on track

I've been reading posts and articles and just getting a little confused and consequently burning through time I don't have at the moment
Can someone look at my code and tell me where I've gone wrong?
Partial Class PayerContacts
Inherits System.Web.UI.Page
Dim connStrDRContacts As String = ConfigurationManager.ConnectionStrings("DRContacts_SQL").ConnectionString
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
navBuild()
End Sub
Protected Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
If IsPostBack Then
LoadContacts(ViewState("objSender"))
End If
End Sub
Private Function navBuild() As Integer
Dim SQLstrDRs As String = "SELECT * FROM DRList"
Dim DbConnDRs As SqlConnection = New SqlConnection(connStrDRContacts)
DbConnDRs.Open()
Dim dtDRsTemp As New DataTable
Dim SQLAdapterDRs As New SqlDataAdapter(SQLstrDRs, DbConnDRs)
SQLAdapterDRs.Fill(dtDRsTemp)
'Loop through each row of the DataView to create HTML table data
Dim NewTableRow As New TableRow
For Each row As DataRow In dtDRsTemp.Rows
'CREATE table with button to display contacts related to client (one to many)
Dim NewTableButton As LinkButton = New LinkButton
NewTableButton.ID = "btnDRName" & NewTableText
NewTableButton.ViewStateMode = UI.ViewStateMode.Enabled
AddHandler NewTableButton.Click, AddressOf LoadContacts
Next
Return 0
End Function
Protected Sub LoadContacts(sender As Object, e As EventArgs)
Dim LoopCount As Integer = 0
Dim SQLstrLoadTable As String = "SELECT * FROM ContactList WHERE DRVendor = '" & sender.Text.ToString & "'"
and so on....
SQLAdapterLoadTable.Fill(dtLoadTableTemp)
Dim NewTableRow As New TableRow
For Each row As DataRow In dtLoadTableTemp.Rows
'CREATE Accordion to display data
NewAccordion.ID = "ContactAccordion" & LoopCount
NewAccordion.Visible = True
blah, blah...
'SET Pane
NewAccordionPane.HeaderContainer.ID = "PaneHeader" & LoopCount
NewAccordionPane.ContentContainer.ID = "PaneContent" & LoopCount
'CREATE button to open ModalPopup to EDIT each record
Dim imgGear As New ImageButton
imgGear.ID = "btnGear" & row!ID.ToString
imgGear.ViewStateMode = UI.ViewStateMode.Enabled
AddHandler imgGear.Click, AddressOf EditRecord
'LOAD Pane
NewAccordionPane.HeaderContainer.Controls.Add(NewHeaderTable)
NewAccordionPane.ContentContainer.Controls.Add(New LiteralControl(NewTableText))
ViewState("objSender") = sender
End Sub
Protected Sub EditRecord(ByVal sender As Object, ByVal e As EventArgs)
'Open ModalPopup to edit record
popup.Show()
pnlAddEdit.Visible = True
End Sub
End Class
The Infinities Loop articles on ViewState and Dynamic Controls should really be read by every Webforms developer: -
http://mocha.mojoskins.com/SharedFiles/Download.aspx?pageid=566&mid=786&fileid=38
http://weblogs.asp.net/infinitiesloop/TRULY-Understanding-Dynamic-Controls-_2800_Part-1_2900_
The examples are in C# but you should be able to figure out what's going on, it's the same base class library after all.

Handling events of dynamically created controls in asp.net

I have a button which is not created dynamically. When I click on that button the number of lines in a textbox are counted. I store that in the variable called count. Depending on value of count I create buttons in panel.
Up to now it is working properly.
Now the click event of those buttons is not firing.
I have tried to google my question. But everywhere I got the same answer. Create the controls in Page_Init event. But how is it possible? I am getting the value of count from a textfile's lines, and that value of count decides how many button will be created in the panel.
Dim btnAllow As New Button
btnAllow.Text = "Allow"
btnAllow.ID = "btA" & x
AddHandler btnAllow.Click, AddressOf btnAllow_Click
btnAllowList.Add(btnAllow)
tdAllow.Controls.Add(btnAllow)
The code for btnAllow_Click
Protected Sub btnAllow_Click(ByVal sender As Object, ByVal e As System.EventArgs)
For x As Integer = 0 To btnAllowList.Count - 1
If sender.ID.SubString(3) = btnAllowList(x).ID.Substring(3) Then
Dim lineCount = IO.File.ReadAllLines(PendingRequestsPath).Length
Dim reader As New System.IO.StreamReader(DocumentViewersPath)
Dim allLines As New List(Of String)
Do While Not reader.EndOfStream
allLines.Add(reader.ReadLine())
Loop
reader.Close()
Dim DocumentViewerAlreadyExists As Boolean = False
For i As Integer = 0 To lineCount - 1
If ReadLine(i, allLines) = lblRequestorsList(x).Text Then
DocumentViewerAlreadyExists = True
Exit For
End If
Next
If DocumentViewerAlreadyExists = False Then
Dim Writer As System.IO.StreamWriter = IO.File.AppendText(DocumentViewersPath)
Writer.WriteLine(lblRequestorsList(x).Text)
End If
Dim line As String = ""
Dim r As IO.StreamReader = IO.File.OpenText(PendingRequestsPath)
Dim strFile As New ArrayList
While r.Peek <> -1 ' Loop through the file
line = r.ReadLine 'Read the next available line
' Check to see if the line contains what you're looking for.
' If not, add it to an ArrayList
If Not line.Contains(lblRequestorsList(x).Text) Then
strFile.Add(line)
End If
r.Close()
' Because we want to replace the content of the file, we first
' need to delete it.
If IO.File.Exists(PendingRequestsPath) Then
IO.File.Delete(PendingRequestsPath)
End If
' Create a StreamWriter object with the same filename
Dim objWriter As New IO.StreamWriter(PendingRequestsPath, True)
' Iterate through the ArrayList
For Each item As ArrayList In strFile
objWriter.WriteLine(item) ' Write the current item in the ArrayList to the file.
Next
objWriter.Flush()
objWriter.Close()
End While
End If
Next
End Sub
This worked for me:
Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
Dim NumberOfControls As Integer = 10
Session("CreateControls") = NumberOfControls
End Sub
Protected Sub btnAllow_Click(ByVal sender As Object, ByVal e As System.EventArgs)
'This will be executed when clicking on the newly created buttons.
End Sub
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
If Session("CreateControls") IsNot Nothing Then
For x As Integer = 0 To Convert.ToInt32(Session("CreateControls"))
Dim btnAllow As New Button
btnAllow.Text = "Allow"
btnAllow.ID = "btA" & x
AddHandler btnAllow.Click, AddressOf btnAllow_Click
Panel1.Controls.Add(btnAllow)
Next
End If
End Sub

i only want the checked items in the arraylist to be added

having trouble only adding the checkboxstatus's that are checked to the gridview.
Protected Sub atasks_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim tasknamelist As New List(Of Boolean)
For Each row As GridViewRow In GridView1.Rows
' Selects the text from the TextBox
Dim checkboxstatus As CheckBox = CType(row.FindControl("tasknamebox"), CheckBox)
tasknamelist.Add(checkboxstatus.Checked)
Next
GridView2.DataSource = tasknamelist
GridView2.DataBind()
UpdatePanel2.Update()
End Sub
GridView1.Rows(0) should just be row (as you declared it)
tasknamelist = checkboxstatus.Checked
is wrong, you assign a bool to a list, try this:
Dim tasknamelist As New List(Of Boolean)
tasknamelist.Add(checkboxstatus.Checked)

Resources