I'm new to asp.net (after programming for years in classic asp). I'm trying to build a page which adds something to a string.
My code is following:
default.aspx
<body>
<form id="form1" runat="server">
<div>
<p><asp:textbox id="tb" runat="server"></asp:textbox></p>
<asp:Panel ID="tbPanel" runat="server"></asp:Panel>
</div>
</form>
</body>
Code behind:
Partial Class demo_Default
Inherits System.Web.UI.Page
Public Property gesStr As String
Set(value As String)
ViewState("gesStr") = value
End Set
Get
Dim o As Object = ViewState("gesStr")
If o Is Nothing Then
Return ""
Else
Return o
End If
End Get
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim anzeigeStr As String = ""
If Page.IsPostBack Then
Else
gesStr = "1;"
End If
tb.Text = gesStr
Dim iButton As New Button
iButton.Text = "add"
iButton.CommandArgument = "1;"
AddHandler iButton.Click, AddressOf add
tbPanel.Controls.Add(iButton)
Me.anzeige()
End Sub
Private Sub add(ByVal sender As Object, ByVal e As EventArgs)
Dim myButton As Button = DirectCast(sender, Button)
Dim addString As String = myButton.CommandArgument
gesStr += addString
End Sub
Private Sub anzeige()
Dim gesArray As Array = Split(gesStr, ";")
For xLauf As Integer = 0 To UBound(gesArray) - 1
Dim anzLabel As New Label
anzLabel.Text = "<p>" & gesArray(xLauf) & "</p>"
tbPanel.Controls.Add(anzLabel)
Next
End Sub
End Class
The problem:
Pressing the button will cause a postBack, but the result of adding won't appear until the button is pressed a second time. The desired result is that the sub displays the correct array within the loop after the first time pressing the button.
Thank you so much for any help!
You need to call the function anzeige() and bind gesStr value to the textbox control each time the button is click. See the code below:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Page.IsPostBack Then
Else
gesStr = "1;"
End If
tb.Text = gesStr
Dim iButton As New Button
iButton.Text = "add"
iButton.CommandArgument = "1;"
iButton.CommandName = "1;"
AddHandler iButton.Click, AddressOf add
tbPanel.Controls.Add(iButton)
End Sub
Private Sub add(ByVal sender As Object, ByVal e As EventArgs)
Dim myButton As Button = DirectCast(sender, Button)
Dim addString As String = myButton.CommandArgument
gesStr += addString
anzeige()
End Sub
Private Sub anzeige()
Dim gesArray As Array = Split(gesStr, ";")
For xLauf As Integer = 0 To UBound(gesArray) - 1
Dim anzLabel As New Label
anzLabel.Text = "<p>" & gesArray(xLauf) & "</p>"
tbPanel.Controls.Add(anzLabel)
Next
'Bind gesStr value to the textbox control
tb.Text = gesStr
End Sub
Related
I'm working on a web app using Visual Studio VB.NET. I have a web form with two panels. I have the code below:
Protected Sub WebForm2_load(sender As Object, e As EventArgs) Handles Me.Load
Dim y As Integer = 1
Protected cr(100) As Button
If con.State = ConnectionState.Open Then
con.Close()
End If
con.Open()
Dim requ As String
requ = "SELECT DISTINCT ENSEIGNEMENTS.Code_Mat From ENSEIGNANT INNER Join ENSEIGNEMENTS On ENSEIGNANT.Code_Ens = ENSEIGNEMENTS.Code_Ens where NomUser='" + un + "' and Sem='S1'"
cmd = New SqlCommand(requ, con)
Dim rd As SqlDataReader = cmd.ExecuteReader()
While rd.Read()
cr(y) = New Button
cr(y).Text = rd("Code_Mat").ToString
cr(y).ID = "btn" & y.ToString
Panel1.Controls.Add(cr(y))
AddHandler cr(y).Click, AddressOf btnc
y = y + 1
End While
End Sub
Protected Sub btnc(ByVal sender As Object, ByVal e As System.EventArgs)
Protected cr1(100) As Button
If con.State = ConnectionState.Open Then
con.Close()
End If
con.Open()
Dim btn As Button()
Dim x As Integer = 1
Dim requete As String
cdmat = CType(sender, Button).Text
'Response.Redirect("TestGroupes.aspx")
requete = "SELECT ENSEIGNEMENTS.Gr FROM ENSEIGNANT INNER JOIN ENSEIGNEMENTS ON ENSEIGNANT.Code_Ens = ENSEIGNEMENTS.Code_Ens WHERE (((ENSEIGNEMENTS.Code_Mat)='" + cdmat + "') AND ((ENSEIGNANT.[NomUser])='" + un + "') AND ((ENSEIGNEMENTS.[Sem])='S1'))"
Dim commande As New SqlCommand
commande = New SqlCommand(requete, con)
Dim reader As SqlDataReader = commande.ExecuteReader()
While reader.Read()
cr1(x) = New Button()
cr1(x).Text = reader("Gr").ToString
cr1(x).ID = "bt" & x.ToString
Panel2.Controls.Add(cr1(x))
AddHandler cr1(x).Click, AddressOf Groupe
x = x + 1
End While
End Sub
Protected Sub Groupe(sender As Object, e As EventArgs)
MsgBox("hhhhh")
End Sub
My problem is that AddHandler cr(y).Click, AdressOf btnc and WenForm2_load work well but AddHandler cr1(x).Click, AdressOf Groupe does not: when I click on a button in Panel2 nothing happens.
You always create the primary buttons (Code_Mat), but you also need to re-create the secondary buttons (Gr) when it posts back, so you'll need to save the variable(s) used to create those secondary buttons.
As a demonstration, I created a new Web Forms project named "testing" with one page named "index.aspx":
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="index.aspx.vb" Inherits="testing.index" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Panel ID="Panel1" runat="server"></asp:Panel>
<asp:Panel ID="Panel2" runat="server"></asp:Panel>
</div>
<asp:Literal id="msg" runat="server">msg</asp:Literal>
</form>
</body>
</html>
Using this code-behind:
Public Class index
Inherits System.Web.UI.Page
Sub Groupe(sender As Object, e As EventArgs)
Dim bn = DirectCast(sender, Button)
msg.Text = bn.CommandArgument
End Sub
Sub CreateSecondaryButtonsHelper(codeMat As String)
Panel2.Controls.Clear()
For i = 1 To 3
Dim bn As New Button With {.Text = "Gr" & i & codeMat, .ID = "bnB" & i, .CommandArgument = "Hello from " & codeMat & i}
AddHandler bn.Click, AddressOf Groupe
Panel2.Controls.Add(bn)
Next
End Sub
Sub CreateSecondaryButtons(ByVal sender As Object, ByVal e As System.EventArgs)
Dim clickedButton = DirectCast(sender, Button)
CreateSecondaryButtonsHelper(clickedButton.Text)
Session("CodeMat") = clickedButton.Text
End Sub
Sub CreateMainButtons()
For i = 1 To 3
Dim bn As New Button With {.Text = "CodeMat" & i, .ID = "bnA" & i}
AddHandler bn.Click, AddressOf CreateSecondaryButtons
Panel1.Controls.Add(bn)
Next
If Session("CodeMat") IsNot Nothing Then
CreateSecondaryButtonsHelper(CStr(Session("CodeMat")))
End If
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
CreateMainButtons()
End Sub
End Class
It is rather dull, but I think it shows what you want to do.
N.B. You should make a new SqlConnection each time you use it and call .Dispose() on it as soon as you've finished using it. Also, using SQL parameters to pass the values instead of making up a string with them will make it more reliable and avoid SQL injection attacks.
I have text box create like that:
Dim Result1 As New TextBox
Result1.ID = "BOX_Result" & a & "_" & i
I want when i click on that textbox to write "OK" and when i double click in cell to put NOT/OK
Important! The TextBox is created Dynamically if i try Result.Click doesn't work, get ne that error: "Result1.Click display error: "Click is not an event of 'System.Web.UI.WebControls.TextBox' "
I try like that but doesn't work:
AddHandler Result1.Click, AddressOf Me.Result1_Click
Private Sub Result1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
Result1.Text = "OK"
End Sub
I want when a person click on that textbox created dynamically but doesn't work click. Thanks for help
You can add these lines to your TextBox definition:
Result1.Attributes.Add("onclick", "this.value = 'OK';")
Result1.Attributes.Add("ondblclick", "this.value = 'NOT/OK';")
In this code, the text "NOT/OK" is displayed when the user double-clicks in the TextBox. In your question, you talk about a double-click "in cell". If that "cell" is not the TextBox, please give some indication of what kind of control it is.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim tb As New TextBox 'Create the new TextBox
AddHandler tb.DoubleClick, AddressOf TB_DoubleClick 'Add a handler to the textbox`s DoubleClick event
AddHandler tb.Click, AddressOf TB_Click
'Set any other properties of textbox you want here....
Me.Controls.Add(tb) 'Add the textbox to the forms controls
End Sub
'This is the textbox Click event handler sub
Private Sub TB_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim tb As TextBox = DirectCast(sender, TextBox) 'Cast the (sender) into a textbox to get access to the textbox`s properties
Result1.Text = "OK"
End Sub
'This is the textbox DoubleClick event handler sub
Private Sub TB_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs)
Dim tb As TextBox = DirectCast(sender, TextBox) 'Cast the (sender) into a textbox to get access to the textbox`s properties
Result1.Text = "NOT OK"
End Sub
I have create a simple exemple for you :
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Result1 As New TextBox
Result1.Text = "BOX_Result"
Dim loc As New Point With {.Y = 117, .X = 111}
Result1.Location = loc
Me.Controls.Add(Result1)
AddHandler Result1.Click, AddressOf Me.Result1_Click
End Sub
Private Sub Result1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim txt As TextBox = sender
sender.Text = "OK"
End Sub
End Class
Hope that you want
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.
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
Thanks to #Angkor Wat I achived a major step towards my goal: dynamic adding of pieces of strings to a string. But I came across another thing I cannot solve.
Here is the script:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="addtostring.aspx.vb" Inherits="demo_addtostring" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<p><asp:textbox id="tb" runat="server"></asp:textbox></p>
<asp:Panel ID="tbPanel" runat="server"></asp:Panel>
</div>
</form>
</body>
</html>
This is the code behind:
Partial Class demo_addtostring
Inherits System.Web.UI.Page
Public Property gesStr As String
Set(value As String)
ViewState("gesStr") = value
End Set
Get
Dim o As Object = ViewState("gesStr")
If o Is Nothing Then
Return ""
Else
Return o
End If
End Get
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Page.IsPostBack Then
Else
gesStr = "1;"
End If
tb.Text = gesStr
Dim iButton As New Button
iButton.Text = "add"
iButton.CommandArgument = "1;"
iButton.CommandName = "1;"
AddHandler iButton.Click, AddressOf add
tbPanel.Controls.Add(iButton)
If Page.IsPostBack Then
Else
anzeige()
End If
End Sub
Private Sub add(ByVal sender As Object, ByVal e As EventArgs)
Dim myButton As Button = DirectCast(sender, Button)
Dim addString As String = myButton.CommandArgument
gesStr += addString
tb.Text = gesStr
anzeige()
End Sub
Private Sub anzeige()
Dim gesArray As Array = Split(gesStr, ";")
For xLauf As Integer = 0 To UBound(gesArray) - 1
Dim anzeigeDiv As New System.Web.UI.HtmlControls.HtmlGenericControl("div")
Dim anzLabel As New Label
anzLabel.Text = gesArray(xLauf)
anzeigeDiv.Controls.Add(anzLabel)
Dim iButton2 As New Button
iButton2.Text = xLauf.ToString
iButton2.ID = "test" & xLauf.ToString
iButton2.CommandArgument = "1;"
iButton2.CommandName = "1;"
AddHandler iButton2.Click, AddressOf add
anzeigeDiv.Controls.Add(iButton2)
tbPanel.Controls.Add(anzeigeDiv)
Next
End Sub
End Class
Clicking on the add-button should add "1;" to gesStr - the dynamic loop-generated buttons should do the same -.- Does anyone have an idea? I would be very thankful for help...
In order for the postback to know about the event handler from the button, the button needs to be recreated prior to the point in the lifecycle where the handler is invoked. In other words, you will always need to recreate the buttons within your Page_Load.
Here is a modification to your code which works:
<form id="form1" runat="server">
<div>
<p><asp:textbox id="tb" runat="server"></asp:textbox></p>
<br />
<asp:Button runat="server" ID="btnAdd" Text="add" CommandArgument="1;" />
<asp:Panel ID="tbPanel" runat="server"></asp:Panel>
</div>
</form>
And code-behind:
Public Property gesStr As String
Get
Dim o As Object = ViewState("gesStr")
If o Is Nothing Then
Return ""
Else
Return DirectCast(o, String)
End If
End Get
Set(value As String)
ViewState("gesStr") = value
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
gesStr = "1;"
End If
tb.Text = gesStr
End Sub
Private Sub add(ByVal sender As Object, ByVal e As CommandEventArgs) Handles btnAdd.Command
Dim addString As String = e.CommandArgument
gesStr += addString
tb.Text = gesStr
CreateNewButton(tbPanel.Controls.Count, addString.Substring(0, addString.Length - 1))
End Sub
Protected Overrides Sub CreateChildControls()
MyBase.CreateChildControls()
Dim gesArray As Array = Split(gesStr, ";")
For xLauf As Integer = 0 To UBound(gesArray) - 1
CreateNewButton(xLauf, gesArray(xLauf))
Next
End Sub
Private Sub CreateNewButton(ByVal xLauf As Integer, ByVal labelText As String)
Dim anzeigeDiv As New Panel
anzeigeDiv.ID = "div" & xLauf.ToString()
Dim anzLabel As New Label
anzLabel.Text = labelText
anzeigeDiv.Controls.Add(anzLabel)
Dim iButton2 As New Button
iButton2.Text = xLauf.ToString
iButton2.ID = "test" & xLauf.ToString()
iButton2.CommandArgument = "1;"
iButton2.CommandName = "1;"
AddHandler iButton2.Command, AddressOf add
anzeigeDiv.Controls.Add(iButton2)
tbPanel.Controls.Add(anzeigeDiv)
End Sub
I've moved the add button, which will always exist, into the aspx page, so that the dynamic panel will only contain the buttons which have been added based on gesStr value.
Dynamic controls must be re-created in every postback see this article for more information.