Migrating ASP.Net User Controls to a DLL in Visual Studio 2010

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()

    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);

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:

  • 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()

    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
<my:mySimple runat="server" id="c1"></my:mySimple>
<my:myLabel runat="server" id="c2"></my:myLabel>

will then be rendered like this:

Sample code is available for download.

19 Responses to Migrating ASP.Net User Controls to a DLL in Visual Studio 2010

  1. […] Migrating ASP.Net User Controls to a DLL in Visual Studio 2010 […]

  2. […] 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’ […]

  3. […] But what about the design time behavior of compiled user controls? […]

  4. […] Migrating ASP.Net User Controls to a DLL in Visual Studio 2010 […]

  5. Josué Clément says:

    Very helpful!! thank you

  6. KenB says:

    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.

    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.

  7. devio says:

    KenB, try this:
    MyUserControl myUserControl = new MyUserControl();

  8. KenB says:

    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.

  9. SOZA says:

    THANK YOUUUUUUUUUUU!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  10. Mike says:

    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!!

  11. you spared me 2 hours of work! +1

  12. bastard says:

    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.

  13. bastard says:

    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 ).

    • devio says:

      You need to wire your event handlers manually, like this:

      protected override void FrameworkInitialize()

      MyButton.Click += MyButton_Click;

      in the .cs file

      • Sergio says:

        Does not work:
        “Public Event Click (..) Is an event and can’t be directly called. Use the RaiseEvent instruction to raise an event.”

  14. bastard says:

    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);

    • Sergio says:

      Does not work:
      “Public Event Click (..) Is an event and can’t be directly called. Use the RaiseEvent instruction to raise an event.”
      “Delegate ‘System.EventHandler’ requires an expression ‘AddressOf’ or a lambda expression as it’s only contructor parameter.”

  15. Joakim says:

    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?

  16. Sergio says:

    For wiring the events of controls, you can also add “onserverclick=’MyControl_MyEvent'” to the markup.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: