Dynamically add CalendarExtender to Textbox subclass server control? - asp.net

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.

Related

Asp.net Dynamic controls dropdownlist and textbox prob

I
have created 2 drop down list and 2 text boxes dynamically in asp.net .i disable text box at run time .i want that when i select item from drop down text box should be enable how to perform this task please help me :(
On SelectedIndexChanged on the dropDownList call a function that sets the textbox enabled = true. To access controls that have been dynamically added you can use FindControl as per C#, FindControl
I think something like this should help you:
In your page's OnInit event:
DropDownList ddl = new DropDownList();
ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged);
placeholder.Controls.Add(ddl); //assuming this is what you use to dynamically show the dropdown list
TextBox yourTextbox = new TextBox(); //declare the variable outside to be able to be accessed by other methods, but it must be instantiated here. declaration here is for illustration purposes only
yourTextBox.Enabled = false;
placeholder.Controls.Add(yourTextBox);
Inside the instantiated event handler:
void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
yourTextbox.Enabled = true;
}

Losing <asp:Label> Text value from ViewState for dynamically added control

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

Postback From Controls inside Composite Web Control

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.

Adding to page control collection from inside a user control

I have an asp.net usercontrol which represents a "popup" dialog. Basically, it's a wrapper for the jQuery UI dialog which can be subclassed to easily make dialogs.
As part of this control, I need to inject a div into the page the control is used on, either at the very top or very bottom of the form so that when the popup is instantiated, it's parent is changed to this div. This allows "nested" popups without the child popup being trapped inside the parent popup.
The trouble is, I can't find a safe way to inject this div into the page. A usercontrol doesn't have a preinit event, so I can't do it there, and calling Page.Form.Controls.Add(...) in Init, Load or PreRender causes the standard exception "The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."
I thought I had found a solution by using...
ScriptManager.RegisterClientScriptBlock(Page, Me.GetType, UniqueID + "_Dialog_Div", containerDiv, False)
... which seemed to work well normally, but recently a coworker tried putting an UpdatePanel inside the dialog and now she's getting the error "The script tag registered for type 'ASP.controls_order_viewzips_ascx' and key 'ctl00$ContentBody$OViewZips_Dialog_Div' has invalid characters outside of the script tags: . Only properly formatted script tags can be registered."
How are you supposed to add controls to the pages control collection from inside a user control?
I'm not sure why you really need to add this div to the page's form, but this should work:
Public Class WebUserControl1
Inherits System.Web.UI.UserControl
Private Sub UC_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
AddHandler Me.Page.Init, AddressOf Me.Page_Init
End Sub
Private Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs)
Dim dialogDiv As New Panel
dialogDiv.ID = "DialogDiv"
If Not Page.Form.Controls.Contains(dialogDiv) Then
Page.Form.Controls.AddAt(0, dialogDiv)
End If
End Sub
End Class
How to implement it in C#. I'm always getting the error The control
collection cannot be modified on Load, PreRender
I need a Literal Control to be added to my master page's head from a user control. The literal control will contain the css link.
Do you want to add the literal to the HeadContent-ContentPlaceHolder control in the master or to the page's header(the html head element)? However, here i show both.
Here's the codebehind of your UserControl:
public partial class UC_AddToMaster : System.Web.UI.UserControl
{
private void Page_Init(object sender, System.EventArgs e)
{
this.Page.Init += UC_AddToMaster_Init;
}
private void UC_AddToMaster_Init(object sender, EventArgs e)
{
Literal literal = new Literal{ Text = "Hi World!" };
// if you want to add it to the header of the page:
if (!Page.Header.Controls.Contains(literal))
{
Page.Header.Controls.AddAt(0, literal);
}
// if you want to add it to the master's HeadContent ContentPlaceHolder control:
var siteMaster = Page.Master as SiteMaster;
if (siteMaster != null)
{
if (!siteMaster.Head.Controls.Contains(literal))
{
siteMaster.Head.Controls.AddAt(0, literal);
}
}
}
}
For the HeadContent approach mentioned above i've provided following property in the master:
// in the master
public ContentPlaceHolder Head { get { return this.HeadContent; } }
Therefore i needed to cast the page's master to it's actual type(SiteMaster here) in the UserControl. Otherwise i couldn't access this property.
Usercontrol doesn't have a PreInit event, but nothing's stopping you from adding a handler to the Page PreInit event in your UserControl:
Page.PreInit += new EventHandler(Page_PreInit);
edit - you're right - you can't capture PreInit from a usercontrol, though I'm surprised you can't - but you can still change the page controls collection by adding code to the constructor of the UserControl. I tried this and it works.
public MyUsercontrol()
{
Page page = (Page)HttpContext.Current.Handler;
Literal lit = new Literal();
lit.Text="text";
page.Controls.Add(lit);
}
Adding an event handler to Page.PreInit in the constructor compiles but it never fires.
(end edit)
That said, I'm not exactly sure why this is necessary to achieve your goal. Why don't you just have your dialog control render it's own div in-line wherever you drop it into the form, and use that as the parent, instead of trying to create one somewhere else in the form? I can't think of why it would be important for it to physically be rendered at the beginning or end of the form. It's a dialog so it will always be invisible until you use it, right?

ASP.NET WebControl & Page - Adding controls (like TextBox) dynamically

I'm trying to create a custom server control (WebControl) with a text box.
I add asp.net textbox to the custom control in CreateChildControls override. In OnInit override I add event handler to TextBox.TextChanged.
Everything works, except that TextChanged never fires. I looked at viewstate and it looks like my textbox never saves its Text property in the viewstate. I've tried to set Text in various places, including constructor, but nothing works.
How can I get TextBox dynamically added to WebControl to save it's Text in viewstate and get TextChanged event to fire?
I would greatly appreciate an example of WebControl code behind with TextBox being added dynamically and TextChanged event being fired.
The dynamically created control must be created again in each post back, (the pageInit event is the better option) for the event to be fired.
BTW, if you want the TextChanged event to generate a postback you must also set the AutoPostback of the control to true.
fixed it. dynamic control must be created and added in Init event. It must be assigned an ID without special ASP.NET symbols ('$' or ':' inside custom ID will break things). All properties must be assigned after control is added to the controls tree.
here's a working example for Page codebehind:
private readonly TextBox _textBoxTest = new TextBox();
protected void Page_Init( object sender, EventArgs e )
{
this.form1.Controls.Add( _textBoxTest );
_textBoxTest.Text = "TestBoxTest";
_textBoxTest.ID = "TestBoxTestId";
_textBoxTest.TextChanged += this._textBoxTest_TextChanged;
}
void _textBoxTest_TextChanged( object sender, EventArgs e )
{
_textBoxTest.Text = "Worked";
}
for WebControl place init code in OnInit override
This will help you out. In short, you need to handle the viewstate for your Dynamically added control on your own.

Resources