After sketching the problem of creating User Control Libraries in VS 2010 and various ways to solve it (some of them no longer supported or cumbersome to use), here is a solution that works in VS2010.![]()
We start with a web application project containing a couple of ascx controls, and migrate them into a library.
First, we create a Class Library project and implement a base class which loads the information contained in the ascx and instantiates a Control:
public class UserControl : System.Web.UI.UserControl
{
protected override void FrameworkInitialize()
{
base.FrameworkInitialize();
string content = String.Empty;
Stream stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(GetType(), GetType().Name + ".ascx");
using (StreamReader reader = new StreamReader(stream))
{
content = reader.ReadToEnd();
}
Control userControl = Page.ParseControl(content);
this.Controls.Add(userControl);
}
}
Screenshot of web application and user control library in a VS solution:

A simple user control containing only text and markup, such as
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="mySimple_org.ascx.cs" Inherits="MyCtrlWeb.mySimple" %> this is my simple control
can be converted into a library-based control in these steps:
- change the Build Action of the .ascx file from Content to Embedded Resource
- remove all attributes in the Control declaration
- delete the designer.cs file
- empty the .ascx.cs file (the .ascx.cs file needs to exist, otherwise the compiler will issue a file not found error)
<%@ Control Language="C#" %> this is my simple control
For users controls containing other controls and program code, perform the following operations:
- copy the ascx from the web application to the user control library
- change the Build Action of the .ascx file from Content to Embedded Resource
- remove all attributes in the Control declaration
<%@ Control Language="C#" %> this is my <asp:Label runat="server" ID="label">Label</asp:Label> control
- create a .cs file with the same name as the .ascx (i.e., for the control myLabel.ascx, create a myLabel.cs file)
- derive the newly created class from the UserControl class loading the ascx
public partial class myLabel : UserControl
{
- copy the member declaration of the contained controls from the .designer.cs file, and subsequently delete .designer.cs
protected global::System.Web.UI.WebControls.Label label;
- retrieve references to the controls contained in the ascx in the control’s FrameworkInitialize() method
protected override void FrameworkInitialize()
{
base.FrameworkInitialize();
label = (Label)this.FindControl("label");
}
- cut and paste the control’s code-behind into the newly created class, and leave the original code-behind file empty
- compile
- add reference to the library in the web project
- embed the new control in a web form
<%@ Register TagPrefix="my" Assembly="MyWebCtrls" Namespace="MyWebCtrls" %> <my:mySimple runat="server" id="c1"></my:mySimple> <my:myLabel runat="server" id="c2"></my:myLabel>
- optionally, add system.web/compilation/assemblies/add assembly and system.web/pages/controls/add tagPrefix settings to your web.config
- execute
My sample page
this is my page <h2>hi</h2> <my:mySimple runat="server" id="c1"></my:mySimple> <h2>hey</h2> <my:myLabel runat="server" id="c2"></my:myLabel> <h2>bye</h2>
will then be rendered like this:


[...] Migrating ASP.Net User Controls to a DLL in Visual Studio 2010 [...]
[...] Events of ASCX Controls after ParseControl After you loaded your control definition from the ascx and retrieved the embedded controls using FindControl(), you notice that the child controls’ [...]
[...] But what about the design time behavior of compiled user controls? [...]
[...] Migrating ASP.Net User Controls to a DLL in Visual Studio 2010 [...]
Very helpful!! thank you
This was very helpful. I was able to get it working for my project except for I am also recursively loading my usercontrol by calling LoadControl. When I remove the recursive load everything is good, however, I need the recursive load. It is building a treeview of sorts.
Example:
MyUserControl myUserControl = (MyUserControl)LoadControl(“MyUserControl.ascx”);
This of course no longer works since the .ascx is embedded. Any ideas on how to get around this?
Thanks in advance.
KenB, try this:
MyUserControl myUserControl = new MyUserControl();
Controls.Add(myUserControl);
Thanks! So simple I’m embarrassed. I built the recursive control some time ago and for some reason went down the path of LoadControl. Had my blinders on yesterday and I didn’t even think to try something so simple.
THANK YOUUUUUUUUUUU!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I found two improvements in my experience, which you might confirm.
*First, let’s say you have two UC’s you want to apply this too, and the second UC is embedded in the markup of the first. When Page.ParseControl(content); gets hit for the embedded UC, the Page object will be null, therefore we should be overriding OnInit instead of FrameworkInitialize.
*Second, Controls in the markup that are embedded in a ContentTemplate aren’t registered by FindControl(“xyz”). They have to be done via something like:
SaveBtn = InputWindow.ContentContainer.FindControl(“SaveBtn”)
Wish there was a way to automate this without knowing exactly which controls on the page have Content Templates on them!!
you spared me 2 hours of work! +1
jesus christ… adding an usercontrol from a dll OUGHT TO be simple. I’ve been trying this since yesterday untill i found this.
Amazing the amount of docs for vs 2005 and almost none ( that works without reinventing the wheel or without nuclear science behind it) to vs 2010.
uhoh, and what about if i want to have an button in my user control, where do i put de CS code ? ( i have a dropdowlist and a button as search ).
You need to wire your event handlers manually, like this:
protected override void FrameworkInitialize()
{
base.FrameworkInitialize();
MyButton.Click += MyButton_Click;
}
in the .cs file
Does not work:
“Public Event Click (..) Is an event and can’t be directly called. Use the RaiseEvent instruction to raise an event.”
Oh thx i already have done ( but forgot to post here)
thx anyway
btn_search = this.FindControl(“btn_search”) as Button;
btn_search.Click += new EventHandler(btn_search_Click);
Does not work:
“Public Event Click (..) Is an event and can’t be directly called. Use the RaiseEvent instruction to raise an event.”
And
“Delegate ‘System.EventHandler’ requires an expression ‘AddressOf’ or a lambda expression as it’s only contructor parameter.”
Thanks for this article. It’s the best on this topic I could find.
I’ve been searching for a way to add the UserControls created with this method to the Toolbox, but have found nothing. If I add a proper WebControl to the same control library then it will show in the Toolbox, but the User controls don’t show.
Do you (or anyone else reading) have a solution?
For wiring the events of controls, you can also add “onserverclick=’MyControl_MyEvent’” to the markup.