Saturday, July 19, 2008

How to make better appearance of your custom control in Visual Studio.

How to make better appearance of your custom control in Visual Studio.

In the previous article Creating Custom Controls in ASP .Net I have covered the technical approach for creating custom control.

Here I will explain how to improve the appearance of your custom control
Their are two ways in which this job can be done.
1) By decorating your control and control properties with some design time attributes.
2) By making your own control designer.

Decorating your control and control properties with some design time attributes:
.Net provides various design time attributes that can be applied on control or on property to take control over the design aspects of the control. You can do lots of things with this attributes let’s say:

One can choose the default event or default property for their controls.

One can assign the description to the property that is displayed in the last section of the property window when the property is selected.

One can categorize their additional properties in property window. This would be helpful when the property window is switched to "Categorized" mode.Etc...

Their are lots of such attributes with which you can playaround.
Some of them I have described below.

Attributes you can apply to your control class:

DefaultEvent - This attribute specifies the default event for your control. So when a control is double clicked, the event handler is automatically created for this event.

DefaultProperty - This attribute specifies the default property for your control. So when you open the property window for your control, this property will be focused by default.

ToolboxData - This attribute allows you to specify any tags that are added to the markup of your control whenever it is added to the page.

ToolboxItem - This attribute allows you to block the control from appearing in the toolbox.

TagPrefix - This attribute allows you to manage the html markup for the registration tag of your control.

Attributes you can apply to your control property:

Bindable - Displays a data binding dialog box for the property.

Browsable - This attribute allows you to block the property from appearing in Property window.

Category - This attribute allows you to group properties in a particular stencil. The property will appear under this category in the property window.

DefaultValue - This attribute allows you to give default value for the property.

Description - This attribute allows you to specify the description for the property. This description is displayed below in the property window when the property is selected.

Editor - This attribute allows you to specify the custom editor window for the property. Examples of custom editor are ImageUrlEditor, MailFileEditor,  MdbDataFileEditor,  UrlEditor etc...

EditorBrowsable - This attribute allow you to block a property from being display in the Intellisense.


Example Source Code
private string _ImageUrl = "";
[Category("My Custom Properties")]
[Description("Specify path of the image to be displayed.")]
[Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
[DefaultValue("")]
[UrlProperty]
[Bindable(true)]
public string ImageUrl
{
    get { return _ImageUrl; }
    set { _ImageUrl = value; }
}
Making your own control designer:
Control Designer help to take control over the appearance of the control when they are drag dropped in the page. One can also create a smart tag that can help user to easily configure some properties of your control. Example: Some of the .Net controls like FormView, DetailsView, GridView have smart tags that help users to easily configure some important properties like Datasource, Templates etc. I will try to cover How to make smart tag controller in my next article.

Example Source Code
using System;

using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;


[assembly: TagPrefix("myControlLib", "myUcl")]
namespace myControlLib
{
public class myImageDesigner : ControlDesigner
{
myImage objmyImage;
public override string GetDesignTimeHtml()
{
if (objmyImage.ImageUrl.Trim().Length == 0)
{
return "Please set Image URL Property!";
}
else
{
return base.GetDesignTimeHtml();
}
}
public override void Initialize(IComponent component)
{
objmyImage = (myImage)component;
base.Initialize(component);
return;
}
}
[Designer("myControlLib.myImageDesigner,myControlLib")]
[ToolboxBitmap(typeof(myImage), "myImageLogo.bmp")]
[ToolboxData(@"<{0}:myImage runat=""server"" ImageUrl="" "" ImageName="" "" ImageDescription="" "" />")]
public class myImage : WebControl
{
public myImage() { }
private string _ImageUrl = "";
[Category("My Custom Properties")]
[Description("Specify path of the image to be displayed.")]
[Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
[DefaultValue("")]
[UrlProperty]
[Bindable(true)]
public string ImageUrl
{
get { return _ImageUrl; }
set { _ImageUrl = value; }
}
private string _ImageName = "";
[Category("My Custom Properties")]
[Description("Specify name of the image to be displayed.")]
public string ImageName
{
get { return _ImageName; }
set { _ImageName = value; }
}
private string _ImageDescription = "";
[Category("My Custom Properties")]
[Description("Specify description of the image to be displayed.")]
public string ImageDescription
{
get { return _ImageDescription; }
set { _ImageDescription = value; }
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.AddAttribute("onmousemove", "javascript:document.getElementById('" + this.UniqueID + "_divDescription').style.display='';");
writer.AddAttribute("onmouseout", "javascript:document.getElementById('" + this.UniqueID + "_divDescription').style.display='none';");
writer.AddAttribute(HtmlTextWriterAttribute.Src, _ImageUrl);
writer.RenderBeginTag(HtmlTextWriterTag.Img);
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.Write("Name : " + _ImageName);
writer.RenderEndTag();
writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none");
writer.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + "_divDescription");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.Write("Description : " + _ImageDescription);
writer.RenderEndTag();
base.RenderContents(writer);
}
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Div;
}
}
}
}


Note: Do not forget to add a .bmp image named ("myImageLogo.bmp") to this project. This image would be displayed as the icon for your control in the toolbox. You can also create .bmp file using inbuilt .Net design tool. Just click on the added .bmp file to open this editor.
Your bmp should be 16x16 pixels in size.


To add custom control to your toolbox refere
How to add custom control in Visual Studio Toolbox.