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   
GeneralRe: The Challengemember_jaso17 Sep '03 - 13:31 
Puco,
 
good work, that's the conclusion I came to as well.
 
I had to create the cs files and compile them manually then place them in the bin directory.
Bit of a bummer if your still developeing and constantly changing the codebehind cs files.
But I guess that's what happens when you use notepad.
 
I was originally hoping that the .NET framweork was clever enough to realise that the references to codebehind that were made in the "@ Reference" directive should be compiled prior to runtime. I have given up on that hope now Smile | :)
 
Thanks for going to the effort in replying puco. I have ended up going berserk and extending the page class, then inheriting from the new basepage class to give all my pages headers and footers automatically without having to code for it in all pages.
 
Cheers,
 
JasonP.
Canberra, Australia
GeneralRe: The ChallengememberMalby10 Nov '03 - 13:19 
Can't you use the Src attribute?
 
Src
Specifies the source file name of the code-behind class to dynamically compile when the page is requested. You can choose to include programming logic for your page either in a code-behind class or in a code declaration block in the .aspx file.
Note RAD designers, such as Visual Studio .NET, do not use this attribute. Instead, they precompile code-behind classes and then use the Inherits attribute.
 
Page.aspx:
<%@ Page Language="C#" Src="Page.aspx.cs" Inherits="DefaultPage" %>
<html>
<head></head>
<body>
<asp:Label runat="server" id="blah" />
</body>
</html>
 

Page.aspx.cs:
 
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
 
public class DefaultPage : Page
{
protected Label blah;
private void Page_Load(Object sender, EventArgs e)
{
blah.Text = "HelloWorld";
}
}
 

 
it all works fine for me?

GeneralRe: The ChallengememberMalby10 Nov '03 - 13:20 
My label control with an id of blah got removed from the html part.. but add that in, and you're laughing
GeneralRe: The Challengemember_jaso10 Nov '03 - 14:35 
I suspect that your example is much simpler than "the challenge". If you use only a textbox and a value, yeah it works.
 
The inclusion of dynamically generated web controls in "the challenge" requires the pre-compilation of the code-behind. Having to pre-compile the code-behind was what I was trying to avoid. It seems that there is no way to do that unless using something like Visual Studio (which pre-compiles the code-behind for you). I don't use Visual Studio at the moment, so was investigating ways to avoid the constant recompilation of code-behind whilst in the active development phase.
 
JasonP.
Canberra, Australia
GeneralRe: The Challenge - Solution?sussAnonymous24 May '05 - 3:28 
I know this is a couple of years late, but I have had exactly the same problem recently, and as there is no solution posted here I thought it might be useful for others to see what I did.
 
Basically, create your user control and code behind exactly as above then use reflection to access methods and properties. this is obviously a roundabout way of doing things, but if you envisage debugging the control more than the code that accesses it, it's a reasonable solution.
 
So, instead of:
 
(MyControlClass)Page.LoadControl("control.ascx");
 
Just return it as a Control:
 
Control c = Page.LoadControl("control.ascx");
 
Then you can use the System.Reflection classes to call methods and set properties - so assuming a pointless parameterless public String Test() "hello world" style method:
 

Type ft = c.GetType();
 
MethodInfo mi = ft.GetMethod("Test");
String hello = (String)mi.Invoke(c, null);

 
The second parameter of Invoke is an object[] for any methods taking parameters you need. See the .NET documentation of Type and MethodInfo for more details.
 
Hope this may be of use to someone!
GeneralYou assume we all use Visual Studiomember_jaso20 Aug '03 - 20:47 
Unfortunately, I am not using Visual Studio.
As such I am having dramas, specificall runtime errors.
 
The page I am building is coded totally in notepad, with the following structures.
 
THE PAGE
- webpage.aspx
- webpage.aspx.cs
THE CONTROL
- mycontrol.ascx
- mycontrol.ascx.cs
 
I am doing it this way to completely seperate the look-and-feel from the back-end code.
This way, others can alter the look and feel of the page, without me having to worry about them messing about the underlying code.
 
When using Visual Studio, it seems to pre-compile all the pages and place the dll's in the bin directory, so they are accessible at runtime. Without Visual Studio, it seems that I'll have to compile them manually. It's only a problem whe I need to use dynamically created UserControls, which , as you can imagine is a rather important part of the development process.
 
Is there a way to get around this? Is anyone else having the same problems? Am I the only person in the universe not developing in Visual Studio??
 

 
JasonP.
Canberra, Australia
GeneralRe: You assume we all use Visual StudiomemberStefan Prodan3 May '07 - 7:30 
Visual Studio is free(see the express products) so I think you are the only developer on codeproject that is using notepad to develop asp.net applications Smile | :)
 
http://stefanprodan.wordpress.com

Generalasp.netmemberjagadeeshkel15 Aug '03 - 20:39 
how can i add image to header control (.ascx) during run time from another .aspx fileSleepy | :zzz:
GeneralForm Statement Error...memberMikeRoad12 Aug '03 - 13:13 
Following your example, I'm trying to place a UserControl which consists of some ASP WebControls (Buttons, primarily), and call it programmatically. I keep getting an error stating that the Button must be placed inside of a form tag. Naturally, I can't do this, since I'm calling it programmatically.
 
Further, I need to be able to create instances of the control on the fly and, most importantly, place them in specific locations on my web form.
 
Any thoughts or help? I'm a relative newbie to .NET and I just can't get this one figured out. Thanks in advance!
GeneralRe: Form Statement Error...membersnowsurfer300018 Aug '03 - 12:49 
Place Form tags around the html that contains the placeholder control.   I place a <form runat="server"> tag after the <body> tag to control the postback events for every control used in the page, including the controls in my UserControls.
 
TC

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