When should I choose a custom control rather than a user control?
Pick a custom control when you need a compiled, reusable control across many projects with Toolbox support. Use a user control for simple, page‑local reuse.
ASP.NET gives you many built‑in controls, but sometimes you need your own. A custom server control is compiled into a class that you can drop on many pages. It shows up in the Toolbox, supports properties and events, and ships as a single assembly.
Why pick a custom server control over a user control? A user control is great for quick UI reuse, but it lives in a single project and is harder to share. A custom control compiles into a DLL, so you can reuse it across sites, version it, and get design‑time support.
You create a control by inheriting from a base class like WebControl or CompositeControl. Override lifecycle methods to render HTML, expose public properties for settings, and raise events so the hosting page can react.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace LegacySamples
{
// Tiny label that renders a with a prefix
public class HelloLabel : WebControl
{
public string Text { get; set; } = "Hello";
public string Prefix { get; set; } = "[info]";
protected override void Render(HtmlTextWriter writer)
{
// Output: [info] Hello
writer.RenderBeginTag(HtmlTextWriterTag.Span);
writer.Write($"{Prefix} {Text}");
writer.RenderEndTag();
}
}
}
// Example: add the control in a page
using LegacySamples;
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var hello = new HelloLabel { Text = "Welcome", Prefix = "Site" };
PlaceHolder1.Controls.Add(hello);
}
}
For richer behavior, use CompositeControl. It lets you compose child controls, wire up events, and expose a simple API to the page.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace LegacySamples
{
// Simple search box + button that raises a server event
[ToolboxData("<{0}:SearchBox runat=\"server\" />")]
public class SearchBox : CompositeControl
{
public event EventHandler Search;
TextBox _query;
Button _go;
protected override void CreateChildControls()
{
_query = new TextBox { ID = "q" };
_go = new Button { ID = "go", Text = "Search" };
_go.Click += (s, e) => Search?.Invoke(this, EventArgs.Empty);
Controls.Add(_query);
Controls.Add(_go);
}
public string Query
{
get { EnsureChildControls(); return _query.Text; }
set { EnsureChildControls(); _query.Text = value; }
}
}
}
Tips: keep rendering simple and predictable. Prefer properties with clear defaults. Use ViewState only when you need to persist values across postbacks. Document which HTML the control emits so teams can style it with CSS.
Distribution: build the control into a class library, sign it if needed, and reference the DLL from your Web Forms app. You can add it to the Toolbox and drag it onto pages. For global reuse, install it in the Bin folder or GAC.
Pick a custom control when you need a compiled, reusable control across many projects with Toolbox support. Use a user control for simple, page‑local reuse.
Expose .NET events on the control and raise them from child control handlers or lifecycle methods. The hosting page subscribes to those events.
Yes. Build a class library DLL and reference it from each app. Put the DLL in the Bin folder or GAC if your policy allows.