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


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)

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

this is my 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

  • 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

hi

hey

bye

will then be rendered like this:

Sample code is available on GitHub.

19 thoughts on “Migrating ASP.Net User Controls to a DLL in Visual Studio 2010

  1. Pingback: Handling tilde (~) paths in ASCX correctly using ParseControl « devioblog

  2. Pingback: Wiring Events of ASCX Controls after ParseControl « devioblog

  3. Pingback: ASP.Net UserControl Life Cycle in DesignMode « devioblog

  4. Pingback: Series: ASP.Net User Control Libraries « devioblog

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

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

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

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

  9. 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.”

  10. 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.”

  11. 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?

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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.