AspNet4YouTop 10sDevelopers WorldForums
Home
About
ASPNet Books
ASPNet Sites
ASPNet Hosters
View Articles
Search Articles
Authors
View Forums
 
Quick Menus
HOME
About
AspNet4You Forums
Articles
Authors
Search
Articles Summary
Articles(RSSFeed)
AspNet Books
AspNet Sites
AspNet Hosters
 Top 10 ASP.NET Books 
Professional ASP.NET 1.1
Essential ASP.NET With Examples in C#
ASP.NET Unleashed
Programming Data Driven Web Applications with ASP.NET
Professional ASP.NET Web Services
Beginning ASP.NET 1.1 with Visual C# .NET 2003
Programming Microsoft ASP.NET
Beginning ASP.NET Databases Using VB.NET
ASP.NET Security
Developing Microsoft ASP.NET Server Controls and Components
More...
 Top 10 ASP.NET Hosters 
WebHost4Life
DiscountASP.NET
MaximumASP
Brinkster
ORCS Web
myhosting.com
ISQSolutions
ASPwebhosting.com, LLC
Active ISP
Aquest Hosting
More...
 Top 10 ASP.NET Sites 
Asp.Net
GotDotNet
4GuysFromRolla.com
123aspx.com
EggHeadCafe.com
CShrp.Net
.NET 247
DevelopersDex.com
Csharp-Corner.com
dotnetspider
More...
Search Articles
Google
ASPNET4YOU      
Category:   Search Type:   Match Type:  
Dynamic Loading of User Control with ViewState Preserved (Live Demo)
Author: Saha, ProdipPosted: 10/27/2005 9:20:46 PM

Dynamic Loading of User Control with ViewState Preserved (Live Demo) 

Many Programmers stay away from loading User Control dynamically on the Web Form because of the complexity associated with it's state management and event handling. It is easy to load a User Control dynamically once you understand the ASP.Net page creation model. In this article, I would like to show you how easy it is to implement the dynamic creation of User Control if you simply do it in the correct way. Let the ASP.Net take care of the complexity while you can concentrate on your business logic. The article will accompany a Live Demo and a downloadable complete source codes.

Dynamic Loading of User Control with ViewState Preserved (Live Demo)

Download the complete source code DnyCtrl.zip

I was inspired by Victor Garcia's article- Learning to play "catch-up". I read the other related articles and they talked about creating user control during the early stage (i.e. Init or Load) of page creating life cycle. After reading the "catch-up" theory, I have learned that is not true. You can create the control (dynamically) event after the page load event and it still maintains the view state.

So, Where (in what event) do we add the control? Well, due to the very nature of the dynamically added control you have to live with the fact that the control must be loaded each time the parent page loaded (postback or non-postback). This is where the tricks begin and I will clarify them soon.

Let me give you a very brief over view of this simple project. I have only one Web Form (LoadDynamicControl.aspx) and two User Controls (Users.ascx and Address.ascx). I put the user controls in a sub-directory called Controls. There are couple of LinkButtons to load the appropriate user control on demand and I add them to a PlaceHolder on the page. Each of the user control has couple of text boxes and a button. We need the text boxes to test view state and we need the button to test event handler on the control. Now, let's take a look how the pages look like. Just to keep it simple I will only mention the required HTML tags and the codes but you can get the complete codes in the download above.

LoadDynamicControl.aspx:

<asp:label 
	id="Label1" 
	runat="server" 
	ForeColor="Blue" 
	Width="100%">Dynamic Control with view state

<asp:LinkButton 
	id="lnkUser" runat="server" 
	CommandArgument="User.ascx" 
	CommandName="User.ascx">Show User

<asp:LinkButton 
	id="lnkAddress" 
	runat="server" 
	CommandArgument="Address.ascx" 
	CommandName="Address.ascx">Show Address

<asp:PlaceHolder 
	id="PlaceHolder1" 
	runat="server">
						

					

LoadDynamicControl.aspx.cs:
Controls must be loaded every time the page is loaded. Page_load event would be an ideal place to load the control. This, however, would not work if the control must be added in other events such as linkButton click event which comes after the page_load event. We attempt to load the control in the page_load event if the control name of the currently loaded control is available. If the same control is loaded in the page load event we avoid reloading it in the subsequent event (like LinkButton.Click). It is very important that we assign the ID attribute of the newly loaded control. Otherwise, The view state may not work properly.

/******************************************************************
* Dynamically loaded control MUST be loaded every time the page
* is loaded or reloaded. I am using the ViewState to track
* the name of currently loaded control. 
* ************************************************************** */

private void Page_Load(object sender, System.EventArgs e) 
{
	
	PrintStatus("");

	try
	{
		
			String ContentID=(String)ViewState[CURRENTLY_LOADED_CONTROL];
			if(ContentID!=String.Empty &&ContentID!=null)
			{
				DynamicLoadControl(ContentID);
			}
			

	}
	catch(Exception ex)
	{
		PrintStatus(ex.Message);
	}
}

/*******************************************************
* Load the dynamic control provided the control name.
* Control in this example is located in the Controls
* sub-folder of the application.
* It is very important that we assign the ID attribute
* of the newly loaded control. Otherwise, The view state
* may not work properly. 
* **************************************************** */

private void DynamicLoadControl(String ControlName)
{
	try
	{
		
		Control ctrl=this.LoadControl(Request.ApplicationPath +"/Controls/" +ControlName);
		
		ctrl.ID=CURRENTLY_LOADED_CONTROL_ID;

		//Clear the Control place holder
		PlaceHolder1.Controls.Clear();

		//Add the control to the place holder
		PlaceHolder1.Controls.Add(ctrl);

		/*******************************************************
		* The ControlName must be preserved to track the 
		* currently loaded control.
		* **************************************************** */
		ViewState["LoadedControl"]=ControlName;	
	}
	catch(Exception ex)
	{
		throw ex;
	}
}


/********************************************************
* This event is fired after the Page_load event. We don't
* want to reload the control of the same control already
* loaded in the page_load event.
* **************************************************** */

private void lnkUser_Click(object sender, System.EventArgs e)
{
	/********************************************************
		* This event is fired after the Page_load event. We don't
		* want to reload the control of the same control already
		* loaded in the page_load event.
		* **************************************************** */
	PrintStatus("");

	try
	{
		ProcessLinkButtonClick(sender);	
	}
	catch(Exception ex)
	{
		PrintStatus(ex.Message);
	}
}


/********************************************************
* This event is fired after the Page_load event. We don't
* want to reload the control of the same control already
* loaded in the page_load event.
* **************************************************** */

private void lnkAddress_Click(object sender, System.EventArgs e)
{
	
	PrintStatus("");

	try
	{
		ProcessLinkButtonClick(sender);	
	}
	catch(Exception ex)
	{
		PrintStatus(ex.Message);
	}
}

private void ProcessLinkButtonClick(object sender)
{
	/*********************************************************
	* Helper function to process linkButton click handler
	* logic.
	* ****************************************************** */
	try
	{
		LinkButton lnk=(LinkButton)sender;
		String ContentID=lnk.CommandArgument;
		if(ContentID!=String.Empty &&ContentID!=null)
		{
			String AlreadyLoadedContent=(String)ViewState[CURRENTLY_LOADED_CONTROL];
			if(AlreadyLoadedContent==null ||AlreadyLoadedContent!=ContentID)
			{
				DynamicLoadControl(ContentID);
			}
		}	
	}
	catch(Exception ex)
	{
		throw ex;
	}
}
					

There is no code in the user control other than printing the contents of the text boxes to a label on click of the button. Button itself is on the user control.

User.ascx:

	First Name:
	<asp:TextBox 
		ID="txtFname" 
		Runat="server">
	
	Last Name:
	<asp:TextBox 
		ID="txtLname" 
		Runat="server">
	
		<asp:Label 
		ID="PrintLabel" 
	Runat="server">
	
	<asp:Button 
		ID="btnUser" 
		Runat="server" 
		Text="Print User">
	
					

Address.ascx:

	City:
	<asp:TextBox 
		ID="txtCity" 
		Runat="server">
	
	State:
	<asp:TextBox 
		ID="txtState" 
		Runat="server">
	
	<asp:Label 
		ID="PrintLabel" 
		Runat="server">
	
	<asp:Button 
		ID="btnAddress" 
		Runat="server" 
		Text="Print Address">
	
					

Have a question or comment? Please visit Questions & Answers Forum


Prodip K. Saha
The Architect of
WWW.ASPNET4YOU.COM.

Terms and Conditions