I am adding controls to a page programatically in the code behind. I add an asp:Label and set it's Text value. I add an asp:TextBox and set it's Text value. Both Text values are returned in the Response and displayed in the browser. All fine so far.
The user performs an action that causes a postback. I re-load the dynamically added asp:Label and asp:TextBox. When the Response is returned to the browser, only the asp:TextBox Text value is displayed. The asp:Label Text value is not.
If I inspect the HTML I can see the asp:Label control (rendered as an HTML span tag) but no value.
How can I get the code to automatically re-load the Text value of an asp:Label on each postback? Why is the behaviour different for an asp:Label and an asp:TextBox? I do not want to have to manually re-set the Text value on each postback.
Here is some code similar to what I am doing (placeHolderNameplates is an asp:PlaceHolder control on the aspx page):
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
If Not Page.IsPostBack Then
Dim lbl As Label = New Label()
lbl.ID = "xxx1"
lbl.Text = "yo"
placeHolderNameplates.Controls.Add(lbl)
Dim tb As TextBox = New TextBox
tb.ID = "xxx2"
tb.Text = "yoyo"
placeHolderNameplates.Controls.Add(tb)
Else
Dim lbl As Label = New Label()
lbl.ID = "xxx1"
placeHolderNameplates.Controls.Add(lbl)
Dim tb As TextBox = New TextBox
tb.ID = "xxx2"
placeHolderNameplates.Controls.Add(tb)
End If
What you need to do is add the control to the placeholder before setting the values, so it should be
Dim lbl As Label = New Label()
placeHolderNameplates.Controls.Add(lbl)
lbl.ID = "xxx1"
lbl.Text = "yo"
See these posts for details:
http://www.yakkowarner.com/2008/01/aspnet-dynamic-controls-and-viewstate.html
http://codebetter.com/jefferypalermo/2004/11/25/key-to-ensuring-dynamic-asp-net-controls-save-viewstate-level-300/
Before they are added to the page, they have not initialized themselves. When a dynamic control is added to another control, the new control plays catch-up to get to the stage that the parent control is in. For instance, if in your Page_Load, you add a textbox, it will play catch-up and go through its Init and Load phases. This is important beceause it will start tracking its viewstate. Values added before it is tracking viewstate won’t make it to viewstate and will be lost on PostBack.
It seems like dynamically created controls won't be added to the ViewState automatically. The TextBox Control retains it's value however because of it's nature of being rendered to a <input type="text" value="xyz" /> html element.
Have a look at this article:
http://www.codeproject.com/Articles/3684/Retaining-State-for-Dynamically-Created-Controls-i
Hey check thsi site MSDN
You have to add your control with following event( so viewstate maintain automaticly)
override protected void OnInit(EventArgs e)
example of Add Dynamic control
http://support.microsoft.com/kb/317794/en-us
Related
I have searched this site for what I need, but none of the answers just quite fits my needs. So here's the deal:
I am dynamically loading a usercontrol to aspx page along with some buttons like this:
Dim uc As UserControl
Dim btns As New List(Of LinkButton)
uc = LoadControl("path_to_ascx")
btns.Add(New LinkButton With {.ID = "btnid", .Text = "Sometext"})
uc.GetType().GetProperty("tblButtons").SetValue(uc, btns, Nothing)
holder2.Controls.Add(uc) 'holder2 is an id of a PlaceHolder
An this work perfectly fine. The buttons show on the page as expected. Now I am having trouble, how to tell these buttons to rise an event written in aspx page, to which a usercontrol is being loaded to.
Public Sub btnClick(sender As Object, e As EventArgs)
'do stuff
End Sub
Why I want to achieve this? Because I have a pretty complex UserControl which I want to reuse as much as possible, but buttons will do different stuff on every aspx page this UserControl will be loaded to.
Thanks
I have solved my problem. In UserControl, I added dynamic buttons to every row on OnRowCreated event.
I was loading UserControl to aspx with buttons like in my question, I just added an ID property to my usercontrol:
Dim uc As UserControl
Dim btns As New List(Of LinkButton)
uc = LoadControl("path_to_ascx")
btns.Add(New LinkButton With {.ID = "btnid", .Text = "Sometext", .CommandName = "cmdName"})
uc.ID = "UserControl1" 'here I added ID property
uc.GetType().GetProperty("tblButtons").SetValue(uc, btns, Nothing)
holder2.Controls.Add(uc) 'holder2 is an id of a PlaceHolder
And after I add an EventHanlder like this:
AddHandler TryCast(holder2.FindControl("UserControl1").FindControl("grid"), GridView).RowCommand, AddressOf grid_RowCommand
'grid is the ID of GrdiView in UserControl
And here is the event for gridview rowCommand written in aspx code behind:
Protected Sub grid_RowCommand(sender As Object, e As GridViewCommandEventArgs)
If e.CommandName = "someCmdName" Then
'do stuff
Else
'do somthing else
End If
End Sub
Maybe my question was not good enough, because I did not mention, that I will be loading buttons to gridview row on rowCreated event and hook them up to RowCommand for wich I apologise.
If someone knows another way to do this, it would be much appreciated to share.
Regards
I need to display the values from a listbox on a content page in a textbox on a masterpage in ASP.Net using VB.Net
Thanks in advance.
You can try this
Dim txt As Textbox = DirectCast(Master.FindControl("yourTextbox"), Textbox)
txt.text = "your Value here"
So you should run this code on your content page.
I assume your textbox on the masterpage is not in a updatepanel or panel etc. then you need to refer that first. but if not, this should work....
Dim tb As Textbox = DirectCast(Master.FindControl("theNameofYourTextBox"), Textbox)
tb.Text = ListBox.Item.Value (or the equivalent for getting the text value in the listbox)
Let's say we have a composite web control with a combobox and a textbox. Is it possible to build into the control functionality such that when the text in the textbox changes, it posts back and adds the value as an option in the combobox?
I know that I could add an "onchange" handler to the textbox and make something work with Javascript, but that's not really what I'm looking to do. Is there a way to just put like:
Protected Sub txt1_TextChanged(sender As Object, e As System.EventArgs) Handles txt1.TextChanged
combo1.items.add(txt1.Text)
End Sub
in the web control code and it connect to the TextChanged event of the textbox?
In short yes, you should be able to do this.
I don't know what syntax you need for VB, but I have done similar things multiple times in C#. For C# you would add the name of the even handler to the markup of your text box, and set auto postback on the text box to true. Then the code behind event handler does what ever work you need it to.
As a rule I also define a custom event on the web control, and have the event handler for the textbox raise this custome event as well. This gives the option of letting the page that is using the control act on the event as well.
EDIT:
Here is an example with a DropDownList, it was part of a control to look up users within a set of Active Directory domains. If the user changed what domain they had selected we wanted it to search for the previously entered values on the new domain.
Mark-up:
<asp:DropDownList ID="ddl_Domain" runat="server" onselectedindexchanged="ddl_Domain_SelectedIndexChanged" AutoPostBack="True"></asp:DropDownList>
Code behind:
protected void ddl_Domain_SelectedIndexChanged(object sender, EventArgs e)
{
if (UserID != "" || LastName != "" || FirstName != "" || EmailAddress != "")
{
lnk_Find_Click(sender, e);
}
}
Or in the case where I have added a child control dynamically through code I have used this syntax:
DropDownList ddl = new DropDownList();
ddl.ID = "ddl";
ddl.DataTextField = "Text";
ddl.DataValueField = "Value";
ddl.SelectedIndexChanged += This_SelectedValue_Changed;
ddl.AutoPostBack = true;
As I said, I am not sure how to make this work with the Handles syntax of VB but it should be possible.
I have a navigation bar which is dynamically populated with LinkButtons by an ASP repeaterControl.
I have no problem accessing, and setting properties for the clicked LinkButton. This I can do using the sender object from the fired LinkButton. Once a LinkButton is clicked, it is highlighted in bold.
My problem is to clear the bold property of the previously clicked linkButton when a new LinkButton ( another RepeaterItem within the same repeater) is clicked.
Any ideas on this, please? Many thanks!
ps.
I cannot access the buttons through their ID, since they all have the same ID within the repeater.
I have unique arguments on each RepeaterItem (CommandArgument), but when I try to iterate through all linkbuttons, only static linkbuttons are found, none inside the repeater. See below:
Dim c As Control
For Each c In Form1.Controls
If TypeOf c Is LinkButton Then
MsgBox(DirectCast(c, LinkButton).CommandArgument)
End If
Next c
Try this:
For each item as RepeaterItem in YourRepeaterControl.Items
Dim button as LinkButton = item.FindControl("YourLinkButtonId")
If button IsNot Nothing Then
'Do whatever you want here
End If
Next
I'm trying to create a server control, which inherits from TextBox, that will automatically have a CalendarExtender attached to it. Is it possible to do this, or does my new control need to inherit from CompositeControl instead? I've tried the former, but I'm not clear during which part of the control lifecycle I should create the new instance of the CalendarExtender, and what controls collection I should add it to. I don't seem to be able to add it to the Page or Form's controls collection, and if I add it to the (TextBox) control's collection, I get none of the pop-up calendar functionality.
I accomplished this in a project a while back. To do it I created a CompositeControl that contains both the TextBox and the CalendarExtender.
In the CreateChildControls method of the CompositeControl I use code similar to this:
TextBox textbox = new TextBox();
textbox.ID = this.ID + "Textbox";
textbox.Text = this.EditableField.TextValue;
textbox.TextChanged += new EventHandler(HandleTextboxTextChanged);
textbox.Width = new Unit(100, UnitType.Pixel);
CalendarExtender calExender = new CalendarExtender();
calExender.PopupButtonID = "Image1";
calExender.TargetControlID = textbox.ID;
this.Controls.Add(textbox);
this.Controls.Add(calExender);
Of course make sure that the form containing this CompositeControl has a toolkit script manager.
I know this is an old thread, but I came across it when I had a similar question. This is what I ended up implementing, and it works great. If you want the control to BE a TextBox, then simply pump out the extender during the call to Render.
Imports System.Web.UI.WebControls
Imports AjaxControlToolkit
Public Class DateTextBox
Inherits TextBox
Private _dateValidator As CompareValidator
Private _calendarExtender As CalendarExtender
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
_dateValidator = New CompareValidator
With _dateValidator
.ControlToValidate = ID
Rem set your other properties
End With
Controls.Add(_dateValidator)
_calendarExtender = New CalendarExtender
With _calendarExtender
.TargetControlID = ID
End With
Controls.Add(_calendarExtender)
End Sub
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
MyBase.Render(writer)
_dateValidator.RenderControl(writer)
_calendarExtender.RenderControl(writer)
End Sub
End Class
You can easily add ajax calendar in custom server controls. You need to add two reference in your application.
1. AjaxControlToolkit.dll
2. System.Web.Extensions
With the help of second reference we will get all the property of “CalendarExtender” in your custom server controls.
When you are trying to not allow users to type anything in the textbox, but only be filled by the calendar extender and then you try to get the selected date from the textbox control it may be empty string if you have set the textbox property to ReadOnly="True".
Its because read only controls are NOT posted back to the server. Workaround for this is the following:
protected void Page_Load(object sender, EventArgs e)
{
TextBox1.Attributes.Add("readonly", "readonly");
}
Hope it helps.