8 out of 12 rated this helpful - Rate this topic

How to: Create Instances of ASP.NET User Controls Programmatically 

Just as you can programmatically create an instance of any server control on an ASP.NET Web page, you can do the same with a user control.

To create an instance of a user control programmatically

  1. In the user control, be sure that the @ Control directive contains a ClassName attribute that assigns a class to the user control.

    The following example sets the ClassName attribute to strongly type a user control.

    <%@ Control className="MyUserControl" %>
    
  2. In the page where you want to work with the user control, create a reference to the user control with the @ Reference directive.

    When you create the user control programmatically, the strong type for your user control is available to the ASP.NET Web page only after you have created a reference to it. For example, the following code creates a reference to a user control created in the MyUserControl.ascx file.

    <%@ Reference Control="MyUserControl.ascx" %>
    
    NoteNote

    You use the @ Reference when you intend to load the control programmatically. You use the @ Register directive when you add a user control to the page declaratively. For details, see How to: Include a User Control in an ASP.NET Web Page.

  3. Create an instance variable for the user control, using the control's class name. The class will be part of the ASP namespace.

    For example, if you want to create an instance of the user control declared as class Spinner, you use syntax such as the following:

    Protected Spinner1 As ASP.Spinner
    

    Protected ASP.Spinner Spinner1;
    
  4. Create an instance of the user control in code by calling the LoadControl method.

  5. Assign property values as necessary, and then add the control to the ControlCollection collection of a container on the page, such as a PlaceHolder control.

    NoteNote

    When you add controls to the ControlCollection object using the Add method, they are placed in the collection in the order they are processed. If you want to add a control to a specific position in the collection, use the AddAt method and specify the index location where you want to store the control.

Example

The following example shows an ASP.NET Web page that loads a user control programmatically. The page includes an @ Reference directive to specify the control's file. The LoadControl method reads the file and instantiates it as a control that can be added to the page.

<%@ Page Language="C#" %>
<%@ Reference Control="~/Controls/Spinner.ascx" %>
<script runat="server">
private ASP.Spinner Spinner1;
protected void Page_Load(object sender, EventArgs e)
{
    Spinner1 = (ASP.Spinner)LoadControl("~/Controls/Spinner.ascx");
     // Set MaxValue first.
    Spinner1.MaxValue = 20;
    Spinner1.MinValue = 10;
    PlaceHolder1.Controls.Add(Spinner1);
}

protected void Button1_Click(object sender, EventArgs e)
{
    Label1.Text = Spinner1.CurrentNumber.ToString();
}
</script>

<html>
<head id="Head1" runat="server">
  <title>Load User Control Programmatically</title>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <asp:PlaceHolder runat=server ID="PlaceHolder1" />
      <br />
      <asp:Button ID="Button1" runat="server" 
        Text="Button" 
        OnClick="Button1_Click" />
      <br />
      <br />
      <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
    </div>
  </form>
</body>
</html>

See Also

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
runtime error in asp.net 2.0

tried to 'get' user control property in page_prerender but got 'Object reference not set to an instance of an object'. Code:



public partial class Cuisenaire_cms_Default : System.Web.UI.Page
{

public ASP.cuisenaire_cms_taskbar_ascx TaskBar;


protected void Page_Load(object sender, EventArgs e)
{


try
{
ASP.cuisenaire_cms_taskbar_ascx TaskBar = (ASP.cuisenaire_cms_taskbar_ascx)LoadControl("TaskBar.ascx");

//Caution!!!!!!!!!!!

// error here! Should not use the class with *_ascx, the right one is cuisenaire_cms_taskbar

// Edited by fwang.


TaskBar.UserPage = oPage;
TaskBar.EditPageURL = sEditPageURL;
mTaskBar.Controls.Add(TaskBar);
}
catch (Exception ex)
{
DisplayError.Text = "Attempt to BuildTaskBar failed due to " + ex.Message;
DisplayError.Style.Add("display", "block");
}

}


protected void Page_PreRender(object sender, EventArgs e)
{
sPageMode = TaskBar.PageMode;

}

}

Also tried to get property at the bottom of Page_Load but it had not yet been set.

When is the user control Page_Load event run in relation to the container page's events?

Does work in NET 3.5 but only if you use 'Web Site Project Type'

The 'Creating Instances of ASP.NET User Controls Programmatically' technique does work in NET 3.5, but only if you create an ASP.NET website using the 'web site project type' (File -> New -> Website) insted of the 'web application project type' (Create: Project... web project), which is the default project type in Visual Studio 2008.

The Web application project model lets you create a Web application whose structure and build semantics closely resemble the project model introduced with Visual Studio .NET 2003 applications. The default Web site project model uses the directory structure to define the contents of the project. In this model, there is no project file, and all files in the directory are part of the project.

The types under (File -> New -> Website) are a relatively older type of project which is based strictly on the file system contents (i.e. no project file). You can create one of these on your local file system, but the largest benefit is that you can create/open websites that are located on an IIS server or via an FTP connection to a hosting service.

The types under (File -> New -> Project) are based on the same project system used by other projects, were you have a .csproj or .vbproj file that keeps track of the contents of your project. These web applications are compiled before deploying (which has some benefits and drawbacks), but are developed on your local machine until you deploy them. They can be deployed through Visual Studio's Copy Web Site or Publish Web Site tools, or with the Web Deployment Project add-in.

Publishing Error in ASP.NET 2.0

I also found that using ASP.<control name> to reference the variable causes the automatic builds to break under ASP.NET 2.0 and MS Build projects.

The solutuion that I used to get my web site published was to un-check 'Allow this precompilled Site to be updatable' in VS2005.

On another note, I also tried using the technique 'Works just fine. Target Framework is 3.5.' listed above in VS2008 (.NET 3.5) was not succussful at all. I could not get either an ASP reference to work or a <control name> without the 'ASP.' to work.

Works just fine. Target Framework is 3.5.

public partial class _Default : System.Web.UI.Page
{
private Spinner Spinner1;

protected void Page_Load(object sender, EventArgs e)
{
Spinner1 = (Spinner)Page.LoadControl("~/Spinner.ascx");
Spinner1.MaxValue = 20;
Spinner1.MinValue = 10;
PlaceHolder1.Controls.Add(Spinner1);
}
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = Spinner1.CurrentNumber.ToString();
}


}

Precompilation error

This technique worked fine until I tried publishing the website by precompilation. I get errors saying that my user control classes do not exist under the ASP namespace.

Code:

ASP.Recommendations recommendations = (ASP.Recommendations)Page.LoadControl(userControlVirtualPath);

Error:

Error 43 The type or namespace name 'Recommendations' does not exist in the namespace 'ASP' (are you missing an assembly reference?)

MS Build consideration

Using ASP.<control name> to reference the variable causes the automatic builds to break under ASP.NET 2.0 and MS Build projects. User controls could be referenced without the "ASP" at the beginning to avoid this issue.

Removing 'ASP' from ASP.<control name> did not work for me.

C# Keywords are Case-sensitive
Since C# is case-sensitive, step 3 for C# should actually be protected ASP.Spinner Spinner1;