Introduction to Developing a Custom Web Control.






3.90/5 (7 votes)
This article explains the development of a custom web control using C#.
Introduction
Every organization has got its own controls for faster development of software. My organization has a standard way for displaying information, errors and warnings on the Web application. So I thought why not make it into a control so that different projects can use the same control and have full control on the look and feel to make it gel into the project UI. Though I have been working on C# components for the past two years this was the first opportunity to develop a custom control for the UI developers. I was totally amazed by the power of custom web controls and the design time support of the Visual Studio IDE.
Points of interest
-
Editor at Design Time
InfoImage
property is used to set the image URL for the Information. The special attribute of this code was theEditor
property which enables a window for navigating the local file images and selecting those images that we require:[Bindable(true), Category("Information Details"), DefaultValue(""), Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] public string InfoImage{ get{ return this._InfoImage; } set{ this._InfoImage = value; } }
-
Hiding inherited properties at design time
Since the custom control is inherited from the
System.Web.UI.WebControls.WebControl
class it has got some default properties like theforecolor
,backcolor
etc..AccessKey
is one of them which is shown at design time. I didn't want this property to be shown to the user at design time. So there is a special attribute calledBrowsable
which if set tofalse
, does not show the property at design time.[Browsable(false), Bindable(false)] public override string AccessKey { get { return base.AccessKey; } set { base.AccessKey = value; } }
-
Hiding of detailed messages
If the
IsDebug
property of the control is set totrue
then the detailed message is shown. This can be useful if you are debugging some page, and if you want to see the detailed error message then theIsDebug
property of the control can be set totrue
:[Bindable(true),Category("Behavior"),DefaultValue(false)] public bool IsDebug{ get{ return this._IsDebug; } set{ this._IsDebug = value; } }
-
Exception Support
This control directly takes an object of the
System.Exception
class and sets the message and stack trace to the control:[Browsable(false),Bindable(true),DefaultValue(null)] public Exception Exception{ set{ this._Exception = value; Text = this._Exception.Message; Details = this._Exception.StackTrace+"\n\n"+this._Exception.TargetSite; MsgType = MessageType.ERROR; } }
-
Rendering the Control
The control is rendered at design time which is very much similar to rendering at runtime. So the control is more like WYSIWYG, but much more easier and convenient:
/// <summary> /// Render this control to the output parameter specified. /// </summary> protected override void Render(HtmlTextWriter output) { if(Enabled){ output.AddAttribute(HtmlTextWriterAttribute.Title, ToolTip,false); output.AddAttribute(HtmlTextWriterAttribute.Cellpadding, this.Cellpadding,false); output.AddAttribute(HtmlTextWriterAttribute.Cellspacing, this.Cellspacing,false); output.AddAttribute(HtmlTextWriterAttribute.Border, BorderWidth.Value.ToString(),false); output.AddAttribute(HtmlTextWriterAttribute.Bordercolor, BorderColor.Name,false); output.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, BorderStyle.ToString()); output.AddAttribute(HtmlTextWriterAttribute.Bgcolor, BackColor.Name,false); output.AddAttribute(HtmlTextWriterAttribute.Width, (Width.Value.ToString()+GetUnit(Width.Type)),false); output.AddAttribute(HtmlTextWriterAttribute.Height, (Height.Value.ToString()+GetUnit(Height.Type)),false); output.AddAttribute(HtmlTextWriterAttribute.Class, CssClass,false); output.RenderBeginTag(HtmlTextWriterTag.Table); RenderHeader(output); RenderInfo(output); if(IsDebug && Details.Length > 0){ RenderDetails(output); } output.RenderEndTag(); } } private void RenderHeader(HtmlTextWriter output){ output.RenderBeginTag(HtmlTextWriterTag.Tr); output.AddAttribute(HtmlTextWriterAttribute.Bgcolor, TdBackColor.Name,false); output.AddAttribute(HtmlTextWriterAttribute.Rowspan,"2", false); output.AddAttribute(HtmlTextWriterAttribute.Width,"0%", false); output.AddAttribute(HtmlTextWriterAttribute.Height,"0%", false); output.RenderBeginTag(HtmlTextWriterTag.Td); switch(MsgType){ case MessageType.ERROR: output.AddAttribute(HtmlTextWriterAttribute.Src, ErrorImage,false); break; case MessageType.WARNING: output.AddAttribute(HtmlTextWriterAttribute.Src, WarningImage,false); break; default: output.AddAttribute(HtmlTextWriterAttribute.Src, InfoImage,false); break; } output.RenderBeginTag(HtmlTextWriterTag.Img); output.RenderEndTag(); output.RenderEndTag(); output.AddAttribute(HtmlTextWriterAttribute.Bgcolor, TdBackColor.Name,false); output.AddAttribute(HtmlTextWriterAttribute.Width,"100%",false); output.AddAttribute(HtmlTextWriterAttribute.Height,"100%",false); switch(MsgType){ case MessageType.ERROR: output.AddAttribute(HtmlTextWriterAttribute.Class, ErrorHeaderTextCss,false); output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write(ErrorHeaderText); output.RenderEndTag(); break; case MessageType.WARNING: output.AddAttribute(HtmlTextWriterAttribute.Class, WarningHeaderTextCss,false); output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write(WarningHeaderText); output.RenderEndTag(); break; default: output.AddAttribute(HtmlTextWriterAttribute.Class, InfoHeaderTextCss,false); output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write(InfoHeaderText); output.RenderEndTag(); break; } output.RenderEndTag(); } private void RenderInfo(HtmlTextWriter output){ output.RenderBeginTag(HtmlTextWriterTag.Tr); output.AddAttribute(HtmlTextWriterAttribute.Bgcolor, TdBackColor.Name,false); switch(MsgType){ case MessageType.ERROR: output.AddAttribute(HtmlTextWriterAttribute.Class, ErrorBreifTextCss,false); output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write(Text); output.RenderEndTag(); break; case MessageType.WARNING: output.AddAttribute(HtmlTextWriterAttribute.Class, WarningBreifTextCss,false); output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write(Text); output.RenderEndTag(); break; default: output.AddAttribute(HtmlTextWriterAttribute.Class, InfoBreifTextCss,false); output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write(Text); output.RenderEndTag(); break; } output.RenderEndTag(); } private void RenderDetails(HtmlTextWriter output){ output.RenderBeginTag(HtmlTextWriterTag.Tr); output.AddAttribute(HtmlTextWriterAttribute.Bgcolor, TdBackColor.Name,false); output.AddAttribute(HtmlTextWriterAttribute.Colspan,"2",false); switch(MsgType){ case MessageType.ERROR: output.AddAttribute(HtmlTextWriterAttribute.Class, ErrorDetailsTextCss,false); output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write(Details); output.RenderEndTag(); break; case MessageType.WARNING: output.AddAttribute(HtmlTextWriterAttribute.Class, WarningDetailsTextCss,false); output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write(Details); output.RenderEndTag(); break; default: output.AddAttribute(HtmlTextWriterAttribute.Class, InfoDetailsTextCss,false); output.RenderBeginTag(HtmlTextWriterTag.Td); output.Write(Details); output.RenderEndTag(); break; } output.RenderEndTag(); }
Further works
Working on Web controls which can fire events, manage client side data and post back the data.