Click here to Skip to main content
Click here to Skip to main content

Programatically include an ASP.NET UserControl in a Web Page

By , 9 Mar 2002
 

Sample Image - ASPNetUserControl2.gif

In one of the earlier articles by Chris Maunder, User controls in ASP .NET, and a similar article by us, ASP.NET User Controls - 1, the highlights of ASP.NET usercontrols have been discussed. These previous artciles demonstrated how to create a UserControl and do declarative inclusion in the web page. This article will discuss programatic inclusion of the UserControls. As you will see that this process is not a rocket science, thanks to ASP.NET framework. A lot of details are already there in Microsoft documentation. But there are some things that you need to be aware of and shall take into consideration.

Todos In Control Declaration

We have seen that a lot of users who have tried to programatically include UserControl on the web page, ran into some compile time and run time errors. And we are no exception to that kind of category of users. Although MS documentation has mentioned steps that need to be followed for programatic inclusion but still some users skipped those steps.

Make sure that you specify the className attribute in @Control directive in the .ascx file implementing your UserControl. What this means is that when you include the control in a web page and create an instance of it then you can refer to the control by its strong type name as specified in className attribute. If you don't specify this attribute, then framework appends _ascx to the class name of that control, defined in codebehind source file, and assigns it to the control. For example in our case we developed a UserControl named SiteHeader. The declaration in the code behind file looks like

public abstract class SiteHeader : System.Web.UI.UserControl

In this case, if you don't specify className attribute in @Control directive then page will load this control with strong name SiteHeader_ascx.

This is one of the problems that people have run into. For example, when we tried to type case the user control to SiteHeader type, it failed. The reason was simple that it was created as type SiteHeader_ascx and not SiteHeader. So @Control in the control's ascx file should look something like this.

<%@ Control Language="c#" AutoEventWireup="false"
	Codebehind="SiteHeader.ascx.cs" <span style="color:red;">classname="SiteHeader"
	Inherits="ASPNet_App.Controls.SiteHeader">

And then you need to follow the procedures for creation and implementation of actual control functionality. In our case we have defined two string properties for the SiteHeader contorl. These properties are used to specify the path for the images that need to be displayed in the control. at load time, in Page_Load event of the control, we check if the path for these images have been specified or not. If there is no path, then we skip the inclusion of asp:Image control. Here is the fragment of the code that we have used.

private void Page_Load(object sender, System.EventArgs e)
{
	if (!IsPostBack)
	{
		// If the file path has been specified for left logo
		// image then add a image control to the cell.
		if (this.m_strLeftLogoImgPath.Length > 0)
		{
			//TODO: Check if the file path is valid or not.
			System.Web.UI.WebControls.Image  leftLogoImg;
			try
			{
				leftLogoImg = new System.Web.UI.WebControls.Image();
				leftLogoImg.ImageUrl = this.m_strLeftLogoImgPath;
				this.LeftLogoCell.Controls.Add(leftLogoImg);
			}
			catch (Exception ex)
			{
				Trace.Write(ex.Message);
			}
		}
	}
}

Todos In WebPage Loading UserControl

When you want to programtically include a UserControl in a web page, the steps are different than those followed for delarative inclusion of a control in web page.

For declarative inclusion of control in the page, you used @Register directive at the top of the page. But for programatic there is going to be a change. You will use @Reference directive. This directive takaes only one attribute, Page or Control. The value of this attribute specifies the file that contains the control or the page that this page should link to during dynamic compliation. This step is very important, otherwise your will get Compiler Error CS0246 indicating that class name or type was not found.

<%@ Reference Control="./controls/SiteHeader.ascx"%>

If you have created your UserControl in a namespace different than the the web application, then you need to add using directive for that namespace if you don't want to use the fully qualified name for the control's type.

using ASPNet_App.Controls;

And then the last step of actually loading the UserControl in the web page. In the Page_Load event for the page, call LoadControl method. This method is defined in System.Web.UI.TemplateControl class and the System.Web.UI.Page class inherits from Template class.

If LoadControl method succeeds, it loads the UserControl from the specified file and returns a reference to that control.

You can access the properties and methods of the loaded control from the reference returned on the previous step.

private void Page_Load(object sender, System.EventArgs e)
{
	if (!IsPostBack)
	{
		// Load the Header UserControl.
		Control hdrCtl = null;
		try
		{
			hdrCtl = LoadControl("./controls/SiteHeader.ascx");
			if (hdrCtl != null)
			{
				((SiteHeader)hdrCtl).LeftLogoImgPath = "..\\images\\ps_logo.gif";
				((SiteHeader)hdrCtl).RightLogoImgPath = "..\\images\\ps_name.gif";
				HeaderCtl.Controls.Add(hdrCtl);
			}
		}
		catch (Exception ex)
		{
			Trace.Write(ex.Message);
		}
	}
}

If all the steps are followed correctly and the proper declarations have been included, then programatic inclusion of UserControl is pretty straight forward.

In the coming days we will be posting more articles demostrating various aspects of UserControl development. So If you have any suggestions or would like to some feature to be demonstrated, please feel free to write us at softomatix@pardesiservices.com or visit us at Softomatix

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Softomatix
Web Developer
United States United States
Member
To learn more about us, Please visit us at http://www.netomatix.com

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionDynamically adding hyperlinks to a panel which is added into the webpartmemberMember 329072229 Jan '09 - 19:50 
Hi,
 
I am working on an Intranet Portal project, in which I am creating dynamic webparts that fetches data from XML. When I generate the webparts It displays the title of the panel but it doesn't display the links within the panel. Below is the code for the same.
 
<code>
WebPartZone wz;
WebPartManager wp = WebPartManager.GetCurrentWebPartManager(Page); GenericWebPart gw; wz = this.WebPartZone1;
int countMenu = xmlData.countNodes("/masterpage/left/left_menu/item");
 
for (int i = 1; i <= countMenu; i++)
{
Panel pan = new Panel();
pan.ID = "Panel" + i.ToString();
String title = xmlData.GetNodeValue("/masterpage/left/left_menu/item[@id='left_menu_item_" + i + "']/title");
pan.Attributes.Add("title", title);
pan.Width = 100;
pan.Visible = true;
int countLinks = xmlData.countNodes("/masterpage/left/left_menu/item[@id=' left_menu_item_" + i + "']/content/content_item");
 
for (int j = 1; j <= countLinks; j++)
{
HyperLink link = new HyperLink();
link.ID = "hyperlink_" + j.ToString();
link.Text = "abc";
link.NavigateUrl= "#";
pan.Controls.Add(link);
}
gw = wp.CreateWebPart(pan);
wp.AddWebPart(gw, wz, (i - 1));
((DynamicWebPart)wp).SetDirty();
}
</code>
 
When I debugged the code I saw that the hyperlinks embedded in the panel are visible in generic web part but they are not visible when I add them to the webpartzone.
 
Hoping for a reply.
 
Thanks.
QuestionView state ???memberkhalidahmad27 Oct '08 - 2:36 
wht about the view state of the user control will it be maintaind or we have to do it manually
 
khalid zaheer

AnswerRe: View state ???memberMike Holpuch27 Oct '08 - 3:02 
You have to do it manually. I usually do this by overriding the OnLoad method. But make sure you call
base.OnLoad( e );
after you do your work so that the rest of the page is loaded.
QuestionHow to use user control in a classmembercagacu2 Jul '07 - 21:45 
How can i use a web user control in a class that i developed?
QuestionMy application name what?memberElvinK18 Nov '06 - 19:09 

You lost me when you said
 
using ASPNet_App.Controls;
 
What's my application's name?
 
The way I am stuck, using Visual Studio 2003 to develop, is like the two horns of a bull ... I do not have a database connection from my IP address for some reason, and the server is not automatically compiling .cs files when I upload them. And also I don't want to get gored, where I have to ftp a dll up (which they may not want me to do.) So basically I am hoping to refer to the full class name without knowing where the C# script gets compiled.
 
I'm working on an application already developed and it appears to have been written by someone who knows Perl. SO far there are no user controls in it at all. But now they want me to do something more complicated. I may be able to work around it in php-style includes, or not.
 
As a perfectionist I hope to overcome all these obstacles with some magic little incantation where I finally guess right class name to use. Yes it is dramatic!
 
(It might turn out the right way out is to copy down the database so I can develop with it.)
 
Sigh | :sigh:
 
Wish me luck.

 
---- ElvinK

GeneralLocations inUserControlsmemberdankyy126 Dec '04 - 21:10 
i create user control dynamically in user control i want to set locations of controls how can i do that?thnks
GeneralEvent Handling in Programatic User ControlsmemberChuck Lane3 Aug '04 - 11:11 
Dear Everyone,
 
I initially had a user control contained in a panel that fired events set up to talk to the web forms page that contained the panel with the user control in it. I initally had added the user control and panel in visual studio, but eventaully when I needed to move the panel around the page it became easier to add this instance of the user control programatically. I have set everything up to do this changing the Register to Reference and etc and everything seems to work fine, however the ItemBound and SelectedIndexChanged events that worked on one defined in Visual Studios designer do not work in the one implemented programatically. Does anyone know if there is a different way or place you have to specify event handlers if you create your user controls on the fly? Thanks in advance. Chuck

GeneralThe Challengemember_jaso20 Aug '03 - 21:57 
Continung my previous rant regarding not being able to compile using code behind with dynamic user controls outside of visual studio. (Something to do with pre-compilation in Visual Studio...)
 
Here's a challenge. Can you convert these two files, which have no codebehind, into 4 files that use codebehind?
 
ORIGINAL FILES
- page.aspx
- control.ascx
 
THE CHALLENGE
- page.aspx
- page.aspx.cs
- control.ascx
- control.ascx.cs
 
If you look at the code you can see that there is nothing to the code. Very straight forward. Adds textboxes using the nominated colours. Of course in the real world you would be doing database lookups, and the control would be much more complicated. But that stuff is unnecesary for this example. If we can convert this to work with codebehind, the rest is relatively easy. It's the concept here that is important.
 

**********************
Src for page.aspx
**********************
<%@ Page Language="C#" Debug="true" %>
<%@ Reference Control="control.ascx" %>
 
<script language="cs" runat="server">
public void Page_Load(Object sender, EventArgs E)
{
   StringCollection sc = new StringCollection();
   sc.Add("orange" );
   sc.Add("green");
   foreach(string myColour in sc)
   {
   MyControlClass ctrl = (MyControlClass)Page.LoadControl("control.ascx");
   ctrl.Colour = myColour;
   ctrl.fillPlaceHolder();
   PlaceHolderForControls.Controls.Add(ctrl);
   }
}
</script>
 
<html>
<head>
   <title>Incident</title>
</head>
<body>
   <h1>Dynamic Controls</h1>
   <form id="f" name="f" method="post" runat="server">
      <asp:PlaceHolder id="PlaceHolderForControls" runat="server" />
   </form>
   </body>
</html>
 

**********************
Src for page.aspx
**********************
<%@ Control Language="cs" AutoEventWireup="false" ClassName="MyControlClass"%>
 
<script language="cs" runat="server">
// Private variable
private string colour = "Default";
 
// Public accessor
public string Colour
   {
   get{return colour;}
   set{colour = value;}
   }
 
   // Public methods
   public void fillPlaceHolder()
   {
   TextBox tb = new TextBox();
   tb.Text = colour;
   A_PlaceHolder.Controls.Add(tb);
   }
</script>
 
<p><asp:PlaceHolder id="A_PlaceHolder" runat="server" /></p>
 

************************
Rant continuing
************************
If anyone can do this, and get it to work just by plonking the resultant 4 files into an IIS mapped web space, you win my admiration and respect. I, for the life of me, cannot figure out how it can be done. I though it would be soo simple to seperate the presentation from the code...
 
Regards,
 
JasonP.
Canberra, Australia
GeneralRe: The Challengememberpuco17 Sep '03 - 0:05 
Simple. But when you separate the .aspx file into two files you have to build the resulting .cs files into an assembly a drop the .aspx files into the IIS mapped address space.
 
So if you want to separate the files here are some instructions.
 
1. Create a template .cs file, which looks like this:
 
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
// and maybe som other default namespaces
 
//
 
namespace
{
class
{
 
}
}
GeneralRe: The Challengememberpuco17 Sep '03 - 0:25 
Simple. But when you separate the .aspx file into two files you have to build the resulting .cs files into an assembly a drop the .aspx files into the IIS mapped address space.
 
So if you want to separate the files here are some instructions.
 
1. Create a template .cs file, which looks like this:
 
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
// and maybe som other default namespaces
 
//[explicitly imported namespaces]
 
namespace
{
class
{
[enumerate all server controls]
 
[drop all code from serverside script blocks]
}
}
 
where
[explicitly imported namespaces] are the ones in aspx which are imported throught <%@ Import .... %>
 
[enumarate all server controls] you have to get a list of all server controls on the page and output them to .cs in the format as VS.NET does:
protected ;
 
2. You have to change the aspx file to inherit from the created .cs file
 
3. You have to build the resulting .cs files into an assembly an copy it to bin folder.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 10 Mar 2002
Article Copyright 2002 by Softomatix
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid