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

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.

Related

how to get the text value of dynamically created textbox

I want to get the value of my textbox that I created dynamically when I click a button
I need to do this cause the value of my textbox is used for retrieve data from database
how could I achieved this thing??
the flow is Button click - creating textbox - filling textbox with value - Button Click - Get Text of textbox
here is my code to make the textbox
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For i As Integer = 0 To 4
textbox = New TextBox With {.ID = "TextBox" & i}
plchld.Controls.Add(textbox)
Next
End Sub
I have tried something like this but the code didn't work
Protected Sub OkButton_Click(sender As Object, e As EventArgs) Handles OkButton.Click
Dim a(5) As String
For i As Integer = 0 To 4
a(i) = CType(plchld.FindControl("Textbox" & i), TextBox).Text
Next
End Sub
thanks in advance for any help
edit for the answer
I've found the way to solve this. I use request.form to get the value of my textbox.
Thanks for anyone that participating
Regards,
Julian
This is how I have done in my asp.net application.
Creating dynamic control
TextBox txtDate = new TextBox();
txtDate.EnableViewState = true;
txtDate.ID = "PreixValue" + 1;
txtDate.Text = "07 Feb 2014"
pnl.controls.add(txtdate);
To retrieve the value from that textbox
DateTime datefrom = DateTime.Now ;
for (int cnt = 0; cnt < Request.Form.Count; cnt++)
{
if (Request.Form.AllKeys[cnt].Contains("Prefixvalue"))
{
int ParamStartPoint = Request.Form.AllKeys[cnt].IndexOf("Prefix") + 4;
int ParamNameLength = Request.Form.AllKeys[cnt].Length - ParamStartPoint;
string[] ControlName = Request.Form.AllKeys[cnt].Substring(ParamStartPoint, ParamNameLength).Split('$');
if (ControlName[0] == "Date From")
{
datefrom = DateTime.Parse(Request.Form[cnt]);
//datefrom has value now
}
}
}
This is how I have done in my web application, but there may be other ways achieve this.
basically when you create Dynamic control in webform this will be available through Request.Form.
hope this helps you.
Protected Sub OkButton_Click(sender As Object, e As EventArgs) Handles OkButton.Click
Dim a(5) As String
For i As Integer = 0 To 4
Dim anotherObj As TextBox = Me.Controls.Item("Textbox" & i)
a(i) =anotherObj.Text
Next
The issue is that dynamic controls are lost on a postback so when the OkButton click event is handled, there is nothing inside your plchld control. You must recreate your controls with the same ID on postback if you want to retrieve the text in the textboxes.
Using your code, all you need to do is on postback determine if the textboxes were created and if so, recreate them.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Determine if the text boxes were created and if so, recreate them.
If CBool(ViewState("TextBoxesCreated")) Then
CreateTextBoxes()
End If
End Sub
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
CreateTextBoxes()
ViewState("TextBoxesCreated") = True
End Sub
Private Sub CreateTextBoxes()
For i As Integer = 0 To 4
plchld.Controls.Add(New TextBox With {.ID = "TextBox" & i})
Next
End Sub
Protected Sub OkButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles OkButton.Click
Dim a(4) As String
For i As Integer = 0 To 4
a(i) = CType(plchld.FindControl("Textbox" & i), TextBox).Text
Next
End Sub
I don't know the full extent of what you are doing but I would suggest not creating them dynamically if you don't need to. Just show or hide the textboxes instead.
Reference: http://www.codeproject.com/Articles/3684/Retaining-State-for-Dynamically-Created-Controls-i

How to keep DataTable persistent?

I have a Gridview filled by a dataTable, filled by a DataAdapter. That's how grid is initially loaded in Page_Load.
To add a search funcionality, I make the same but passing TextBox.Text as parameter to the SELECT... LIKE ... statement.
To add an edit funcionality(a button in every row) I need the previous data in the dataTable, and if I performed a search before editing I need only the result of the search in my dataTable.
The problem is, I don't know how to keep its value alive (persistent), and dataTable has 0 columns when I press teh edit button, so it doesn't display anything to edit.
I guess it happens because I'm using Using, and dataTable is probably getting cleaned after End Using.
In that case, whta can I do to fix it? I thought removing miconn.Close() but it doesn't solve anything, in fact, I don't know if connection is still open after End Using.
Code:
Dim con As New Connection
Dim table As New DataTable()
Private Sub fill_grid()
Using miconn As New SqlConnection(con.GetConnectionString())
Dim sql As String = "SELECT area,lider_usuario FROM AREA"
Using command As New SqlCommand(sql, miconn)
Using ad As New SqlDataAdapter(command)
ad.Fill(table)
GridView1.DataSource = table
GridView1.DataBind()
'miconn.Close()
End Using
End Using
End Using
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
fill_grid()
End If
End Sub
Protected Sub btnSearch_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSearch.Click
Dim miCon As New Connection
Using miconn As New SqlConnection(miCon.GetConnectionString())
Dim sql As String = "SELECT area,lider_usuario FROM AREA WHERE area LIKE #area"
Using command As New SqlCommand(sql, miconn)
command.Parameters.Clear()
command.Parameters.Add("#area", SqlDbType.VarChar).Value = "%" + TextBox1.Text + "%"
Using ad As New SqlDataAdapter(command)
ad.Fill(table)
GridView1.DataSource = table
GridView1.DataBind()
'miconn.Close()
End Using
End Using
End Using
End Sub
Protected Sub EditRow(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
GridView1.EditIndex = e.NewEditIndex
GridView1.DataSource = table
GridView1.DataBind()
End Sub
Protected Sub CancelEditRow(ByVal sender As Object, ByVal e As GridViewCancelEditEventArgs)
GridView1.EditIndex = -1
GridView1.DataSource = table
GridView1.DataBind()
End Sub
BindGrid()
{
var dt = YourMethodReturningDatatable();
ViewState["Table"] = dt;
grid.DataSource = ViewState["Table"];
grid.Databind();
}
page_load
{
if(not ispostback) // not because my 1 key stopped working.
{
BindGrid();
}
}
I would suggest you to make two different functions for filling the data table and binding it. Call the filling function before the !IsPostBack condition and do the binding inside the condition. Here is the sample code:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim table as new DataTable
table = GetData() 'The function that would return a data table
If Not IsPostBack Then
GridView1.DataSource = table
GridView1.DataBind()
End If
End Sub
Private Function GetData() As DataTable
Using miconn As New SqlConnection(con.GetConnectionString())
Dim sql As String = "SELECT area,lider_usuario FROM AREA"
Using command As New SqlCommand(sql, miconn)
Using ad As New SqlDataAdapter(command)
ad.Fill(table)
GetData = table
miconn.Close()
End Using
End Using
End Using
End function
Hope it helps.

asp.net gridview without database

Hi guys I have a question. Is there some way to populate a gridview in asp.net without using a database? I'm using a gridview to show information but I've seen that everytime I try to insert more rows to the grid the last row is changed with a new one and overwrites the data
I'm using the following code:
Dim dtsetinform As New DataSet
Dim datatableinfo As New DataTable("fill")
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
dtsetinform.Tables.Add(datatableinfo )
gridfactura.DataSource = datatableinfo
datatableinfo.Columns.Add("Name") '
datatableinfo.Columns.Add("Quantity")
datatableinfo.Columns.Add("Price")
Session("fill") = datatableinfo
End Sub
Public Sub agregarfilas(ByVal total As Integer)
datatableinfo = Session("fill")
Dim row As DataRow = datatableinfo .NewRow
row("Name") = ddserviciotxt.Text
row("Quantity") = cantidadtxt.Text
row("Price") = total
datatableinfo .Rows.Add(row)
ViewState("tablainViewState") = datatableinfo
datatableinfo .AcceptChanges()
gridfactura.DataSource = datatableinfo
gridfactura.DataBind()
End Sub
Protected Sub btnagregar_Click(sender As Object, e As EventArgs) Handles btnagregar.Click
Dim result As Integer
Dim price As Integer = preciotxt.Text
Dim quantity As Integer = cantidadtxt.Text
result = price * quantity
agregarfilas(result)
End Sub
you need to put the code in the page load in
if not Page.IsPostBack then
your code
end if

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

Maintaining Checkbox State in a Listview Control Pagination ASP.NET

I Have a web form in a asp.net web form 3.5. The listview has a checkbox on the item template, I am trying to retain the state of the checkboxes through pagination . Once I can page through records and preserver this state I need to send this to a print page which takes those ids...I have this working, but it will print only the records on each pagination. Please see live website:
http://rgvpreferred.com/ProviderSearch.aspx
Can you please check my code and suggest how can this be done, the code below is not working.
Protected Sub ListView1_ItemCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewCommandEventArgs) Handles ListView1.ItemCommand
Dim myButtonPrint1 As Button = CType(ListView1.FindControl("printButton1"), Button)
If e.CommandSource Is myButtonPrint1 Then
Dim recordsId As New List(Of String)
For Each lvi1 As ListViewItem In ListView1.Items
Dim chb1 As CheckBox = IIf(lvi1.FindControl("CheckBoxPrintProvider1") Is Nothing, IIf(lvi1.FindControl("CheckBoxPrintProvider3") Is Nothing, lvi1.FindControl("CheckBoxPrintProvider4"), lvi1.FindControl("CheckBoxPrintProvider3")), lvi1.FindControl("CheckBoxPrintProvider1"))
If chb1.Checked = True Then
Dim param1 As String
param1 = DirectCast(lvi1.FindControl("lblId1"), Label).Text
recordsId.Add(param1)
End If
Next
' Store in session to be pulled out in the Printable Page
Session("Records") = recordsId
Response.Redirect("PrintableProviderList.aspx")
End If
End Sub
'Trying to Preserve states
Private ReadOnly Property IDs() As List(Of Integer)
' Create a list of ID's that are selected. ID's is the primary
' Key for this table
Get
If Me.ViewState("IDs") Is Nothing Then
Me.ViewState("IDs") = New List(Of Integer)()
End If
Return CType(Me.ViewState("IDs"), List(Of Integer))
End Get
End Property
Protected Sub AddRowstoIDList()
' Loop through all the current items in the Listview
For Each lvi As ListViewDataItem In ListView1.Items
' Find the checkbox in each row
Dim chkSelect As CheckBox = CType(lvi.FindControl("CheckBoxPrintProvider1"), CheckBox)
' If the checkbox is ticked then add the corresponding ID to our private
' list
If (Not (chkSelect) Is Nothing) Then
' Get the ID from the datakeynames property
Dim ID As Integer = Convert.ToInt32(ListView1.DataKeys(lvi.DisplayIndex).Value)
If (chkSelect.Checked AndAlso Not Me.IDs.Contains(ID)) Then
' Add the ID to our list
Me.IDs.Add(ID)
ElseIf (Not chkSelect.Checked AndAlso Me.IDs.Contains(ID)) Then
' Not checked - remove the ID from our list
Me.IDs.Remove(ID)
End If
End If
Next
End Sub
Protected Sub ListView1_PagePropertiesChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.PagePropertiesChangingEventArgs) Handles ListView1.PagePropertiesChanging
AddRowstoIDList()
End Sub
Protected Sub ListView1_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewSortEventArgs) Handles ListView1.Sorting
AddRowstoIDList()
End Sub
Protected Sub ListView1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles ListView1.ItemDataBound
' Get each Listview Item on DataBound
Dim lvi As ListViewDataItem = e.Item
If (lvi.ItemType = ListViewItemType.DataItem) Then
' Find the checkbox in the current row
Dim chkSelect As CheckBox = CType(lvi.FindControl("CheckBoxPrintProvider1"), CheckBox)
' Make sure we're referencing the correct control
If (Not (chkSelect) Is Nothing) Then
' If the ID exists in our list then check the checkbox
Dim ID As Integer = Convert.ToInt32(ListView1.DataKeys(lvi.DisplayIndex).Value)
chkSelect.Checked = Me.IDs.Contains(ID)
End If
End If
End Sub
you have to save the selected checkboxes before pagination .
see this link. it should help you:
http://evonet.com.au/maintaining-checkbox-state-in-a-listview/

Resources