Developing custom server control in ASP.NET is fun! You are flexible to develop it either inheriting the existing ASP.NET server controls like Button, HyperLink, BoundField or create you own control by inheriting Control/WebControl classes from System.Web.UI namespace. There are dozens of cool and fabulous custom server controls developed by third-parties like Metabuilder or ExcentricWorld. I like to develop the custom server control because the tailored controls can specifically accomplish some jobs that normal shipped-in ASP.NET server controls can't. It serves the purpose on your needs.
There are basic concepts/rules in custom server control development in ASP.NET like :
1. Derive your control class from
System.Web.UI.Control if your control is dealing with non-visual elements or merely render as HTML output. For instance, META tag. Otherwise, your class should inherit from
System.Web.UI.WebControls class if your control is built to have visual appearance to the client.
2. Do not override the
Render() method of in your control if it is inheriting from
System.Web.UI.WebControls class because the method is responsible in rendering the outer tag and control styling to the output stream. Override its
RenderContent() method instead!
protected override void RenderContent(HtmlTextWriter writer)
{
writer.Write("Test");
}
3. When your control inherting the
System.Web.UI.WebControls, its outer tag is <span> by default. You can get rid of this and render any outer tags you want by overriding its
HtmlTextWriterTag.TagKey or
TagName (non-standard HTML tags).
protected override HtmlTextWriterTag TagKey
{
get { return HtmlTextWriterTag.Input; }
}
or
public Button() : base(HtmlTextWriterTag.Input)
{ }
4. Check whether the control is in the <form runat="server"> by
if (Page != null)
Page.VerifyRenderingInServerForm(this);
in either
AddAttributesToRender() or
Render()/RenderContent() method.
5. By default, the tag prefix of your custom server control would be auto-generated. For instance, when you drag and drop your control, the tag would be something like
<cc1:CustomMeta ID="CustomMetaTag1" runat="server" />
As you see, the "cc1" gives no meaning. You can add your own tag prefix by adding
TagPrefixAttribute in the assemblyinfo.cs file.
using System.Web.UI;
[assembly:TagPrefix("SimpleControl", "Alvin")]
Now, it would become like
<Alvin:CustomMeta ID="CustomMetaTag1" runat="server" />
6. Take note of rendering methods of
System.Web.UI.Control class
public void RenderControl(HtmlTextWriter writer) {
if (Visible) {
Render(writer);
}
}
protected virtual void Render(HtmlTextWriter writer) {
RenderChildren(writer);
}
protected virtual void RenderChildren(HtmlTextWriter writer) {
foreach (Control c in Controls) {
c.RenderControl(writer);
}
}
It is wise to call the base class's methods if you intend to override the method like
RenderChildren method to ensure its child controls are recursively rendered.
protected override void RenderChildren(HtmlTextWriter writer)
{
base.RenderChildren(writer);
// do your stuff
}
7. To restrict the control to have NO CHILD CONTROLS, you need to return
EmptyControlCollection(this) to the overidden
CreateControlCollection() method.
protected override ControlCollection CreateControlCollection() {
return new EmptyControlCollection(this);
}
By doing that, no child controls/tags are allowed.
// Allow
<Alvin:CustomMeta ID="CustomMetaTag1" runat="server" />
// Not allow !
<Alvin:CustomMeta ID="CustomMetaTag1" runat="server"></Alvin:CustomMeta>