creating textbox at runtime - asp.net

how to create as many textbox at runtime on button click. And also what will be the id's of textboxes created at runtime and send the value of textbox to next page through session
please someone help me. I've stucked at this point for many days but could not solve it.
thanks
prasanna

To create a textbox at runtime you set it up in your Page_Init like this:
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
' Create dynamic controls here.
TextBox1 = New TextBox()
TextBox1.ID = "TextBox1"
TextBox1.Style("Position") = "Absolute"
TextBox1.Style("Top") = "25px"
TextBox1.Style("Left") = "100px"
Form1.Controls.Add(TextBox1)
TextBox2 = New TextBox()
TextBox2.ID = "TextBox2"
TextBox2.Style("Position") = "Absolute"
TextBox2.Style("Top") = "60px"
TextBox2.Style("Left") = "100px"
Form1.Controls.Add(TextBox2)
End Sub

Creating dynamic controls in ASP.Net can be a little tricky. The reason is any control created after the Page_Init will not be stored in the View State. This means for controls created after the Page_Init, on the page post back the data entered into the control will be lost. Furthermore events will not be fire for the those controls.
A good three part article can be found here
https://web.archive.org/web/20211020131055/https://www.4guysfromrolla.com/articles/081402-1.aspx

Related

Persisting Dynamic ReadOnly Field Past Initialisation

I create a readonly textbox dynamically on page load/init and on the first load (not IsPostBack) I set the text. I also have a button on the page with a click event that changes the content of the textbox. Using another button, I read the text of the textbox. The problem is as follows:
If I click the button that changes the textbox and then click the button that reads the text of the textbox, it gets it fine.
If I just load the page and click the button that reads the text of the textbox, it brings back an empty string
I need both scenarios to bring back a result - whether it's the original text or the new programmatically changed text.
Example code:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim Textbox As New TextBox()
Textbox.ID = "Bob"
Textbox.ReadOnly = True
If Not IsPostBack Then
Textbox.Text = "Initial Text"
End If
Content.Controls.Add(Textbox)
Dim Button As New Button()
Button.Text = "Change text"
AddHandler Button.Click, AddressOf Button_Click
Content.Controls.Add(Button)
End Sub
Protected Sub Button_Click(ByVal sender As Object, ByVal e As EventArgs)
'FindControlRecursive is locally defined - just finds a control based on root control and ID
CType(FindControlRecursive(Content, "Bob"), TextBox).Text = "Hmmmmm"
End Sub
Private Sub Submit_Click(sender As Object, e As EventArgs) Handles Submit.Click
Dim Textbox As TextBox = CType(FindControlRecursive(Content, "Bob"), TextBox)
MsgBox(Textbox.Text)
End Sub
I could just reinitialise the textbox each time but this is just an example and in practice I'll be pulling it from SQL and if I have several read only controls on the page I'd rather get the control to persist its text rather than going back to SQL each time.
I found two ways to solve this, the second being the more favoured approach (depending on situation):
Specifically add the initial text to the viewstate and then set the text on each postback using the value from viewstate:
If Not IsPostBack Then
Textbox.Text = "Initial Text"
ViewState("Bob") = Textbox.Text
Else
Textbox.Text = ViewState("Bob")
End If
Add a PreRender event to the textbox that just sets it text to itself. This takes place after the ViewState starts being tracked so it's added to the viewstate via the control and is persisted across postbacks:
If Not IsPostBack Then
Textbox.Text = "Initial Text"
AddHandler Textbox.PreRender, AddressOf PersistPastInitialLoad
End If
And add new sub:
Protected Sub PersistPastInitialLoad(ByVal sender As Object, ByVal e As EventArgs)
'This is just for example - would need refining for different types of controls
CType(sender, TextBox).Text = CType(sender, TextBox).Text
End Sub
Essentially they both do the same thing - hold the text in viewstate - but it depends on implementation which is the best to use. The first implementation might be a bit easier to read/work with but it would result in redundant viewstate bloat if you click the button to change the textbox text (i.e. you'll have the initial text in viewstate against the viewstate key you created as well as the current text added to viewstate by the control onchange).

Clearing gridview upon certain condition in vb.net

on textbox blank, i wanted to clear my gridview source
But i was not able to do it in vb.net.
After referring several answers i tried following unsuccessfull attempts:
grdUsers.rows.clear() : Does not work with vb.net
grdUsers.DataSource=""
grdUsers.columns.clear()
But it does not worked out.
Please help me to clear my datasource of gridview.
If your DataGridView is bound to a DataSource and you want to clear it then you can use the Nothing keyword followed by a DataBind().
grdUsers.DataSource = Nothing
grdUsers.DataBind()
Here is more information on the DataBind() method.
If you want to clear your rows when the text is empty in TextBox1, you would create a TextChanged event for your textbox ...
Private Sub TextBox1_TextChanged(sender As Object, e As System.EventArgs) Handles TextBox1.TextChanged
If TextBox1.Text.Trim = "" Then
grdUsers.DataSource = Nothing
grdUsers.DataBind()
End If
End Sub

Refreshing an ASP.Net GridView when changes are made to DetailsView

We have an ASP.Net / VB.Net code-behind web form. On this form is a GridView and a DetailsView.
When there is a change in the details view we would like the changes to be reflected in the GridView.
This code is being used to populate the GridView:
Private Sub Teachers_Init(sender As Object, e As EventArgs) Handles Me.Init
' Load the data from the database into the GridView.
'---------------------------------------------------
GridViewSummary.DataSource = theTableAdapter.GetDataAllTeachers
GridViewSummary.DataBind()
End Sub
This coding is being used to reflect the changes in the GridView after a change to the details are made in the DetailsView:
Private Sub DetailsView_ItemUpdated(sender As Object, e As DetailsViewUpdatedEventArgs) Handles DetailsView.ItemUpdated
' Refresh the data so current values are displayed.
'--------------------------------------------------
GridViewSummary.DataSource = theTableAdapter.GetDataAllTeachers
GridViewSummary.DataBind()
End Sub
Is there a way to not need the use of:
GridViewSummary.DataSource = theTableAdapter.GetDataAllTeachers
in the above coding? I know it's just 1 line of code but would like to eliminate it if it's not needed.

ASP.NET bug in event linking of 2nd level+ dynamic controls. Test case included

The Repeater control in the following test case contains two runat="server" DIVs. Each one of them gets a TextBox appened to them through the ItemCreated event of the Repeater. Both of the have AutoPostBack=True, and TextChanged event wired to txt_TextChanged. However, only the TextBox from the first level properly points to the event on the postBack of the page. The second level TextBox also causes the postBack to occur, but its value does not persist in the VIEWSTATE as well as the event does not fire.
Here's a direct link to the test case in a .zip file (uploaded to my personal website), as well as all the code needed. The project is built in VS2010 using .NET Framework 4, but the problem also exists in 1.1, 2, and 3.5.
Anybody has any ideas on what is wrong and how to make this work?
ASPX
<asp:Repeater ID="rep" runat="server">
<ItemTemplate>
<!-- first level works -->
<div id="divOutside" runat="server">
<!-- second level doesn't work -->
<div id="divInside" runat="server"></div>
</div>
</ItemTemplate>
</asp:Repeater>
Code-Behind
Public Class WebForm1
Inherits System.Web.UI.Page
Private Sub WebForm1_Init(sender As Object, e As System.EventArgs) Handles Me.Init
If Not IsPostBack Then
Dim Table As New DataTable()
Table.Columns.Add("Column1")
Dim Row As DataRow = Table.NewRow()
Row("Column1") = ""
Table.Rows.Add(Row)
rep.DataSource = Table
rep.DataBind()
End If
End Sub
Private Sub repTest_ItemCreated(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rep.ItemCreated
' outside
Dim divOutside As HtmlGenericControl = DirectCast(e.Item.FindControl("divOutside"), HtmlGenericControl)
Dim txtInput As New TextBox
With txtInput
.ID = "txtInputOutside"
.AutoPostBack = True
.Text = "Event gets called, value persists accross postBack."
.Width = 400
End With
AddHandler txtInput.TextChanged, AddressOf txt_TextChanged
divOutside.Controls.Add(txtInput)
' inside
Dim divInside As HtmlGenericControl = DirectCast(e.Item.FindControl("divInside"), HtmlGenericControl)
txtInput = New TextBox
With txtInput
.ID = "txtInputInside"
.AutoPostBack = True
.Text = "Event NOT called, value is lost during postBack."
.Width = 400
End With
AddHandler txtInput.TextChanged, AddressOf txt_TextChanged
divInside.Controls.Add(txtInput)
End Sub
Protected Sub txt_TextChanged(sender As Object, e As EventArgs)
End Sub
End Class
Is there any reason why the textboxes have to be added to the divs dynamically? why not just put them in the aspx page with the repeater then on itemdatabound enable/disable or do whatever you need to do. That should work fine.
By the way, if you were to use panels instead of divs your on the fly approach will work.
Here's a link to Microsoft Connect, where I reported this is an official bug:
https://connect.microsoft.com/VisualStudio/feedback/details/652655/asp-net-bug-in-event-linking-of-2nd-level-dynamic-controls
It contains 2 PARTIAL workarounds that work in the uploaded files section, if anybody is interested or encounters the same problem, as well as details to what I found in the Workarounds tab.
To keep it short, it is the order of getting references to the containers and the order the TextBoxes are appended to their appropriate containers which either causes the issue or works as expected.
But, not to forget the most important point, the only reason the first-level TextBox is there in the first place is to showcase what I want as functionality. If the first-level TextBox does not get appended at all, then both workarounds fail to provide any sort of fix. Please keep that in mind when reviewing that problem - finding a workaround that revolves around changing the order of the items is not an actual solution or a fully working workaround!
Thanks everyone for the input!

Why can't I find the AjaxControlToolkit Html Editor Control using FindControl when it's inside an AjaxControlToolkit ReorderList?

I have the latest release of the AjaxControlToolkit, and am using an AjaxControlToolkit Html Editor control inside an AjaxControlToolkit ReorderList. I need to be able to access the "content" property so I can write the value to the database but FindControl doesn't find it.
for instance, I can find a TextBox control inside the ItemCommandEvent:
Protected Sub IncludedSectionComponentsReorderList_ItemCommand(ByVal sender As Object, ByVal e As AjaxControlToolkit.ReorderListCommandEventArgs) Handles IncludedSectionComponentsReorderList.ItemCommand
If e.CommandName = "SaveChanges" Then
Dim txtSectionComponentLabel As TextBox = CType(e.Item.FindControl("txtSectionComponentLabel"), TextBox)
End If End Sub
But I can't find an AjaxControlToolkit Html Editor in the same event:
Protected Sub IncludedSectionComponentsReorderList_ItemCommand(ByVal sender As Object, ByVal e As AjaxControlToolkit.ReorderListCommandEventArgs) Handles IncludedSectionComponentsReorderList.ItemCommand
If e.CommandName = "SaveChanges" Then
Dim editor As Editor = CType(e.Item.FindControl("3Editor"), Editor)
strSectionControlValue = editor.Content
End If
End Sub
I haven't used the AjaxControlToolKit ReorderList control before, but you may need to access something like the "_OnItemDataBound" event. Sometimes controls are shoved in there when a row is being databound and you can't access them as you would think.
Good luck and hope this helps some.
Here's a solution for you:
In this example it's taking content from an aspx page to an ascx page
AjaxControlToolkit.HTMLEditor.Editor txtNotes = (AjaxControlToolkit.HTMLEditor.Editor)Page.FindControl("txtNotes");
txtView.Content = txtNotes.Content;

Resources