![]() |
Web Development »
User Controls »
General
Intermediate
Creating Custom User Control Designers in ASP.NETBy srirambalajiAn article on creating custom User Control designers in ASP.NET. |
C#, VB.NET 1.1, Win2K, WinXP, ASP.NET, WebForms, VS.NET2003, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

A User Control is a server control that can be authored using declarative style as an ASP.NET web page. They provide web developers a quick way to create server controls.
User controls suffer from minimal design-time support in VS.NET. Their properties cannot be edited using Property Grid. This article is an attempt to create Custom Designers for User Controls which allow to edit their properties using Property Grid.
The code below shows a Header User Control which exposes Heading and SubHeading properties to allow the user to provide a heading and subheading for the page.
<%@ Control Language="vb" AutoEventWireup="false"
Codebehind= "Header.ascx.vb" Inherits="CustomDesignersWebVB.Header" %>
<table align="center" ID= "tblHeader">
<tr>
<td><asp:label id="lblHeading" Font-Size="18" Font-Name="Arial"
Font-Bold="True" Runat="server">Heading</asp:label></td>
</tr>
<tr>
<td><asp:label id="lblSubHeading" Font-Size="14" Font-Name="Arial"
Font-Bold="True" Runat="server">Sub Heading</asp:label></td>
</tr>
</table>Public Property Heading() As String
Get
Return lblHeading.Text
End Get
Set(ByVal Value As String)
lblHeading.Text = Value
End Set
End Property
Public Property SubHeading() As String
Get
Return lblSubHeading.Text
End Get
Set(ByVal Value As String)
lblSubHeading.Text = Value
End Set
End Property
<%@ Control Language="C#" AutoEventWireup="false"
Codebehind= "Header.ascx.cs" Inherits="CustomDesignersWebCS.Header" %>
<table align="center" ID= "tblHeader">
<tr>
<td><asp:label id="lblHeading" Font-Size="18" Font-Name="Arial"
Font-Bold="True" Runat="server">Heading</asp:label></td>
</tr>
<tr>
<td><asp:label id="lblSubHeading" Font-Size="14" Font-Name="Arial"
Font-Bold="True" Runat="server">Sub Heading</asp:label></td>
</tr>
</table>public string Heading
{
get
{
return lblHeading.Text;
}
set
{
lblHeading.Text=value;
}
}
public string SubHeading
{
get
{
return lblSubHeading.Text;
}
set
{
lblSubHeading.Text=value;
}
}
Fire up Visual Studio .NET, use the File | New | Project menu item and select Web Control Library project template.
Add a Component Class to the project as shown below:

A Component Class is a class that inherits System.Component.Component. It can be added to the toolbox of VS.NET and can be dragged and dropped onto the design surface, and when selected, its properties are displayed using Property Grid.
Following is the code listing for the HeaderDesigner component class:
private string _Heading ;
private string _SubHeading;
public string Heading
{
get
{
return _Heading;
}
set
{
_Heading=value;
}
}
public string SubHeading
{
get
{
return _SubHeading;
}
set
{
_SubHeading=value;
}
}
Private _Heading As String
Private _SubHeading As String
Public Property Heading() As String
Get
Return _Heading
End Get
Set(ByVal Value As String)
_Heading = Value
End Set
End Property
Public Property SubHeading() As String
Get
Return _SubHeading
End Get
Set(ByVal Value As String)
_SubHeading = Value
End Set
End Property
Header Designer exposes Heading and SubHeading properties to the user. The user sets these properties using a Property Grid.
Open the project containing Header User Control. Add the HeaderDesigner component to the Components tab in the Toolbox, as shown below:

Drag and drop the HeaderDesigner to the design surface. Now you can set the Heading and SubHeading properties using the Property Grid as shown:

Open the code-behind for the page and add the following code:
protected Header Header1;
private void Page_Load(object sender, System.EventArgs e)
{
//Glue code to associate the Usercontrol with the Designer
if(!IsPostBack)
{
CustomDesignersCS.DesignerHelper.BindDesignerToControl(headerDesigner1,
Header1);
}
}
Protected Header1 As Header
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
If Not Page.IsPostBack Then
CustomDesignersVB.DesignerHelper.BindDesignerToControl(HeaderDesigner1, _
Header1)
End If
End Sub
BindDesignerToControl function is the glue code which binds HeaderDesigner properties to the user control properties. It uses Reflection to read Designer properties and associate them with the corresponding properties in the Header User Control.
public class DesignerHelper
{
public static void
BindDesignerToControl(System.ComponentModel.Component designer, Control ctl)
{
BindDesignerToObject(designer, ctl);
}
public static void
BindDesignerToObject(System.ComponentModel.Component designer, Object obj)
{
//Get object properties using Reflection
PropertyDescriptorCollection colWebCtlPropDesc =
TypeDescriptor.GetProperties(obj);
//Get Designer properties using Reflection
PropertyDescriptorCollection coldesignerPropDesc =
TypeDescriptor.GetProperties(designer);
//Loop through all Designer properties
//Each designer property corresponds to webcontrol property
foreach(PropertyDescriptor pd in coldesignerPropDesc)
{
PropertyDescriptor webctlpd = colWebCtlPropDesc.Find(pd.Name, true);
if (webctlpd!=null)
{
//Assign the designer property value to web control's property
webctlpd.SetValue(obj, pd.GetValue(designer));
}
}
}
}
Public NotInheritable Class DesignerHelper _
Public Shared Sub BindDesignerToControl(ByVal designer As _
System.ComponentModel.Component, ByRef ctl As Control)
BindDesignerToObject(designer, ctl)
End Sub
Public Shared Sub BindDesignerToObject(ByVal designer As _
System.ComponentModel.Component, ByRef obj As Object)
'Get object properties using Reflection
Dim colWebCtlPropDesc As PropertyDescriptorCollection = _
TypeDescriptor.GetProperties(obj)
'Get Designer properties using Reflection
Dim coldesignerPropDesc As PropertyDescriptorCollection = _
TypeDescriptor.GetProperties(designer)
'Loop through Designer properties
'Each designer property corresponds to webcontrol property
For Each pd As PropertyDescriptor In coldesignerPropDesc
Dim webctlpd As PropertyDescriptor = _
colWebCtlPropDesc.Find(pd.Name, True)
If Not IsNothing(webctlpd) Then
'Assign the designer property value to web control
webctlpd.SetValue(obj, pd.GetValue(designer))
End If
Next
End Sub
End Class
While working on this article, I discovered that one can set the properties of BasePage class (custom Page class which all pages derive from) using the Property Grid in WebForms Designer.
I am planning to do the following enhancements when time permits:
UserControl" in UserControlDesigner, which lists all the UserControls in the Page. User can pick the UserControl he wants to bind to the designer from the dropdown.
CodeDOMSerializer for the designer which automatically generates the binding code. Feel free to email me your suggestions and comments. I would like to make improvements based on your feedback.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 7 Apr 2005 Editor: Smitha Vijayan |
Copyright 2005 by srirambalaji Everything else Copyright © CodeProject, 1999-2009 Web21 | Advertise on the Code Project |