Walkthrough: Creating a Basic Control Designer for a Web Server Control
This walkthrough demonstrates how to create a basic control designer to provide a design-time user interface (UI) for a Web server control.
When you create a custom ASP.NET server control, you can create an associated designer to render the control in a visual design tool such as Microsoft Visual Studio 2005. The designer enables the host environment to render a design-time UI for the control, so that developers can easily configure the control's properties and content. For more information about designer features and the various designer classes you can associate with a custom control, see ASP.NET Control Designers Overview.
During this walkthrough, you will learn how to:
Create a standard composite control designer and associate it with a composite control.
Create a resizable composite control designer and associate it with a composite control.
Create a basic container control designer with an editable region, and associate it with a WebControl control. This designer enables you to add text to the editable region on the design surface, and you can also drag additional controls into the region.
Reference the custom controls (and their associated designers) on a Web page.
Work with the Web page in Design view in Visual Studio 2005.
Prerequisites
In order to complete this walkthrough, you will need:
Visual Studio 2005, which you will use to create a Web page that hosts your custom controls and their associated designers.
An ASP.NET Web site, for the page that hosts the controls. If you have a site already configured, you can use that site as a starting point for this walkthrough. Otherwise, for details on creating a virtual directory or site, see How to: Create and Configure Virtual Directories in IIS.
Creating Custom Controls and Designers
In this section, you create three basic Web server controls and an associated custom control designer for each of them.
To create a file for the code
In an editor, create a new file named
SimpleControlDesigners
with the appropriate extension for the language you are working in. For example, in Visual Studio 2005, create a new class file namedSimpleControlDesigners.vb
orSimpleControlDesigners.cs
.Add the following namespace references that are necessary for working with the designer classes. Also add a namespace to contain your controls and the associated designers.
Imports System Imports System.ComponentModel Imports System.ComponentModel.Design Imports System.Drawing Imports System.Web.UI Imports System.Web.UI.Design Imports System.Web.UI.Design.WebControls Imports System.Web.UI.WebControls Namespace Samples.AspNet.VB.Controls End Namespace
using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; using System.Web.UI; using System.Web.UI.Design; using System.Web.UI.Design.WebControls; using System.Web.UI.WebControls; namespace Samples.AspNet.CS.Controls { }
Save the file.
Now you are ready to create a composite Web server control and an associated designer. A designer can be in the same assembly as the control or in a different one; in this walkthrough, you create them in the same code file and assembly for convenience.
To create a composite control and an associated designer
Within the namespace you declared in the
SimpleControlDesigners
file, create a public declaration for a composite control class that inherits from CompositeControl, as shown in the following code example.Public Class SimpleCompositeControl Inherits CompositeControl End Class
public class SimpleCompositeControl : CompositeControl { }
Add the public properties shown in the following code example to the class. These will be used to create part of the UI on the Web page.
Dim _prompt As String = "Please enter your date of birth: " Overridable Property Prompt() As String Get Dim o As Object o = ViewState("Prompt") If o Is Nothing Then Return _prompt Else Return CType(o, String) End If End Get Set(ByVal value As String) ViewState("Prompt") = value End Set End Property Overridable Property DOB() As DateTime Get Dim o As Object o = ViewState("DOB") If o Is Nothing Then Return DateTime.Now Else Return CType(o, DateTime) End If End Get Set(ByVal value As DateTime) ViewState("DOB") = value End Set End Property
private String _prompt = "Please enter your date of birth: "; public virtual String Prompt { get { object o = ViewState["Prompt"]; return (o == null) ? _prompt : (string)o; } set { ViewState["Prompt"] = value; } } public virtual DateTime DOB { get { object o = ViewState["DOB"]; return (o == null) ? DateTime.Now : (DateTime)o; } set { ViewState["DOB"] = value; } }
Create a method to add child controls to the composite control. The following method adds two text boxes and a line break that will be visible on the Web page.
Protected Overrides Sub CreateChildControls() Dim lab As New Label lab.Text = Prompt lab.ForeColor = System.Drawing.Color.Red Me.Controls.Add(lab) Dim lit As New Literal() lit.Text = "<br />" Me.Controls.Add(lit) Dim tb As New TextBox() tb.ID = "tb1" tb.Text = DOB.ToString() Me.Controls.Add(tb) MyBase.CreateChildControls() End Sub
protected override void CreateChildControls() { Label lab = new Label(); lab.Text = Prompt; lab.ForeColor = System.Drawing.Color.Red; this.Controls.Add(lab); Literal lit = new Literal(); lit.Text = "<br />"; this.Controls.Add(lit); TextBox tb = new TextBox(); tb.ID = "tb1"; tb.Text = DOB.ToString(); this.Controls.Add(tb); base.CreateChildControls(); }
Create a simple composite control designer class that derives from CompositeControlDesigner to associate with the composite control you just created.
Although there are a variety of UI rendering features you could add to the designer, the following code example simply creates the designer and overrides a key property in the base class to prevent the control from being resized in design view.
Public Class SimpleCompositeControlDesigner Inherits CompositeControlDesigner ' Set this property to prevent the designer from being resized. Public Overrides ReadOnly Property AllowResize() As Boolean Get Return False End Get End Property End Class
public class SimpleCompositeControlDesigner : CompositeControlDesigner { // Set this property to prevent the designer from being resized. public override bool AllowResize { get { return false; } } }
Immediately above the class declaration for the composite control, add a Designer metadata attribute that associates the control with the designer class you just created, as shown in the following code example.
<Designer(GetType(SimpleCompositeControlDesigner))> _ Public Class SimpleCompositeControl Inherits CompositeControl
[Designer(typeof(SimpleCompositeControlDesigner))] public class SimpleCompositeControl : CompositeControl
Save the file.
Now that you have created a custom composite Web server control and an associated designer, you can create a second control that derives from the first. The second control differs only in that its associated designer can be resized on the design surface.
To create a resizable composite control and associated designer
Within the namespace you declared in the
SimpleControlDesigners
file, create a public declaration for a new composite control class that inherits from theSimpleCompositeControl
control you created earlier. The following code example demonstrates a new declaration.Public Class SimpleCompositeControl2 Inherits SimpleCompositeControl End Class
public class SimpleCompositeControl2 : SimpleCompositeControl { }
Associate this control with the CompositeControlDesigner base class.
By default, this example creates a basic, resizable designer for the composite control.
<Designer(GetType(CompositeControlDesigner))> _ Public Class SimpleCompositeControl2 Inherits SimpleCompositeControl End Class
[Designer(typeof(CompositeControlDesigner))] public class SimpleCompositeControl2 : SimpleCompositeControl { }
Save the file.
The first two controls you created were composite controls that you associated with composite control designers. Now you will create a simple control that derives from WebControl, and associate it with a ContainerControlDesigner class. This type of designer is useful when you want to associate a designer with a single custom Web server control and provide a single editable region on the design surface. The custom control you create here does not implement any actual functionality; it exists only to show the features of the ContainerControlDesigner class.
Note |
---|
You could also provide this same functionality using a composite control and designer like those you created earlier. This example is intended only to show how you can use the ContainerControlDesigner class and associate it with a WebControl control. |
To create a Web server control and a container designer with an editable region
Within the namespace you declared in the
SimpleControlDesigners
file, create a public declaration for a new Web server control class, as shown in the following code example.Public Class SimpleContainerControl Inherits WebControl Implements INamingContainer End Class
public class SimpleContainerControl : WebControl, INamingContainer { }
Create a container control designer class to associate with the custom control. Implement two properties: a
FrameStyle
property to contain the style for the designer's frame, and aFrameCaption
property to contain the frame's header text. These properties provide a frame for the control to be visibly rendered and selected on the design surface. The code for the designer and properties is shown in the following code example.Note The ContainerControlDesigner class automatically handles all other aspects of rendering the custom control at design time and providing a single editable region.
Public Class SimpleContainerControlDesigner Inherits ContainerControlDesigner Dim _style As Style ' Add the caption by default. Public Overrides ReadOnly Property FrameCaption() As String Get Return "A Simple ContainerControlDesigner" End Get End Property Public Overrides ReadOnly Property Framestyle() As Style Get If _style Is Nothing Then _style = New Style() _style.Font.Name = "Verdana" _style.Font.Size = New FontUnit("XSmall") _style.BackColor = Color.LightBlue _style.ForeColor = Color.Black End If Return _style End Get End Property End Class
public class SimpleContainerControlDesigner : ContainerControlDesigner { private Style _style = null; // Add the caption by default. Note that the caption // will only appear if the Web server control // allows child controls rather than properties. public override string FrameCaption { get { return "A Simple ContainerControlDesigner"; } } public override Style FrameStyle { get { if (_style == null) { _style = new Style (); _style.Font.Name = "Verdana"; _style.Font.Size = new FontUnit ("XSmall"); _style.BackColor = Color.LightBlue; _style.ForeColor = Color.Black; } return _style; } } }
Associate the designer with the control. Immediately above the class declaration for the Web server control, add the Designer metadata attribute. Note that in this case, as shown in the following code example, you also add the ParseChildren attribute with a false parameter. This tells the design-time parser to treat the inner contents of controls as child controls, rather than as properties. In this case, you want to treat the inner contents of this control as child controls so that you can actually drag other server controls into the editable region at design time, and edit their properties as well.
<Designer(GetType(SimpleContainerControlDesigner))> _ <ParseChildren(False)> _ Public Class SimpleContainerControl Inherits WebControl Implements INamingContainer End Class
[Designer (typeof(SimpleContainerControlDesigner))] [ParseChildren (false)] public class SimpleContainerControl : WebControl, INamingContainer { }
Save the file.
You have created three custom controls and associated control designers with them. All that remains is to compile the controls into an assembly and then work with them in a visual design tool.
To compile the custom controls and designers
Open a command prompt to the folder where you created the
SimpleControlDesigners
file. From this prompt, you can compile the source code into an assembly.Note To run the .NET Framework compilers from this location, you must have already added the path of your .NET Framework installation to your computer's PATH variable. Usually, this path is under the Windows installation directory at \Microsoft.NET\Framework\<version number>. If you have not updated the PATH variable, right-click My Computer, select Properties, click the Advanced tab, and click the Environment Variables button. In the System Variables list, double-click the PATH variable. In the Variable value text box, add a semicolon to the end of the existing values in the text box, and then type in the path of your .NET Framework installation. Click OK to close each dialog box.
Compile the controls in the
SimpleControlDesigners
file into an assembly using the following compile command.csc /r:System.dll /r:System.Design.dll /r:System.Drawing.dll /debug+ /r:System.Web.dll /t:library /out:SimpleControlDesignersCS.dll simplecontroldesigners.cs
vbc /r:System.dll /r:System.Design.dll /r:System.Drawing.dll /debug+ /r:System.Web.dll /t:library /out:SimpleControlDesignersVB.dll SimpleControlDesigners.vb
Move the resulting assembly file to the \Bin folder of the Web site for the page that will host your controls.
Note Visual Studio users who want to compile the controls and designers need to add a reference to System.Design.dll. For more information, see How to: Add a Reference to a .NET or COM Component in a Web Site.
Creating a Web Page to Host the Controls
Now that you have created an assembly with your custom controls and their associated control designers, you will create a Web page in Visual Studio 2005 to reference the controls, see how they appear in Design view, and load the page in a browser.
To create a Web page to host the controls
With your Web site open in Visual Studio 2005, create a new page called ControlDesigners.aspx. At the top of the page, just under the page declaration, add a Register directive to reference the assembly and controls you created previously, as shown in the following code example.
<%@ Page Language="VB" %> <%@ register tagprefix="aspSample" assembly="SimpleControlDesignersVB" namespace="Samples.AspNet.VB.Controls" %>
<%@ Page Language="C#" %> <%@ register tagprefix="aspSample" assembly="SimpleControlDesignersCS" namespace="Samples.AspNet.CS.Controls" %>
Complete the rest of the page as shown in the following code example, to reference each of the three controls you created previously:
SimpleCompositeControl
,SimpleCompositeControl2
, andSimpleContainerControl
. Note that to reference each control, you use the aspSample prefix specified in the Register directive.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Designers Page</title> </head> <body> <form id="form1" runat="server"> <div> <p style="font-family:tahoma;font-size:large; font-weight:bold"> Simple Control Designers </p> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Composite, no-resize</span> </div> <aspSample:SimpleCompositeControl id="SimpleControl1" runat="server" /> <br /><br /> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Composite, resize</span> </div> <aspSample:SimpleCompositeControl2 id="SimpleControl2" runat="server" height="87px" width="238px" /> <br /><br /> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Container</span> </div> <aspSample:SimpleContainerControl id="SimpleControl3" runat="server" height="57px"> Type some content here. </aspSample:SimpleContainerControl> <br /><br /> </div> </form> </body> </html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Designers Page</title> </head> <body> <form id="form1" runat="server"> <div> <p style="font-family:tahoma;font-size:large; font-weight:bold"> Simple Control Designers </p> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Composite, no-resize</span> </div> <aspSample:SimpleCompositeControl id="SimpleControl1" runat="server" /> <br /><br /> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Composite, resize</span> </div> <aspSample:SimpleCompositeControl2 id="SimpleControl2" runat="server" height="87px" width="238px" /> <br /><br /> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Container</span> </div> <aspSample:SimpleContainerControl id="SimpleControl3" runat="server" height="57px"> Type some content here. </aspSample:SimpleContainerControl> <br /><br /> </div> </form> </body> </html>
Save the page.
Now you can test the page in Design view to see how the control designers work.
To demonstrate the design-time rendering of the controls
Switch to Design view for the page.
The controls should appear as they do in the following screen shot. Notice that the second composite control is resizable, and the first is not.
ControlDesigners.aspx page in Design view
Click in the content region of the container control, and type some text content for the control.
Switch to Source view, and locate the source code for the container control. Confirm that the text you typed in the region now appears in the source code.
Switch back to Design view.
Click the frame of the control, position the mouse pointer over one of the resizing icons, and resize the container control.
Click in the editable region of the control at the end of the text content, and press ENTER to add a line break.
Drag a Button control from the Toolbox and drop it into the editable region beneath the text you entered. Drag a Label control from the Toolbox and drop it next to the button. This demonstrates that you can drag child controls into the editable region. If you want, you can set properties on the child controls at design time, and you can add code for the Button control to update the Label control's Text property at run time.
The page with the controls you just added should look similar to the following screen shot.
Container control with child controls
Save the page.
To view the page at run time
Load the page in a browser.
The controls should appear as you customized them in Design view. Your page should look similar to the following screen shot.
Completed control designers Web page
Next Steps
This walkthrough has demonstrated the basic tasks involved in creating a custom control associated with a composite or a container control designer. You created custom controls with designers that allowed you to resize the controls and add text in an editable region in the Design view in Visual Studio 2005. Suggestions for further exploration include:
Investigate the other powerful new features that are available with control designers. For more information, see ASP.NET Control Designers Overview.
Try creating more advanced designer scenarios where you create specialized design-time rendering and take advantage of features such as action lists. For details, see Sample Control Designer with Action Lists and Services.