Creating a Better Designer Experience


Up to this point, we've ignored the Design view experience. In other words, we've ignored the question of how our custom controls appear in the Visual Web Developer or Visual Studio .NET Design view.

You can modify the appearance of your control in Design view in two ways. You can apply design-time attributes to the control, or you can associate a ControlDesigner with your control. We'll explore both methods in this section.

Applying Design-Time Attributes to a Control

Design-time attributes enable you to modify how control properties appear in Design view. Some attributes are applied to the control itself, whereas other attributes are applied to particular properties of a control.

Here is the list of the design-time attributes you can apply to a control:

  • DefaultEvent Enables you to specify the default event for a control. When you double-click a control in Visual Web Developer or Visual Studio .NET, an event handler is automatically created for the default event.

  • DefaultProperty Enables you to specify the default property for a control. When you open the Property window for a control, this property is highlighted by default.

  • PersistChildren Enables you to specify whether child controls or properties are persisted as control attributes or control contents.

  • ToolboxData Enables you to specify the tag added to a page when a control is dragged from the toolbox.

  • ToolboxItem Enables you to block a control from appearing in the Toolbox.

Here is the list of design-time attributes you can apply to a control property:

  • Bindable Enables you to indicate to display a Databindings dialog box for the property.

  • Browsable Enables you to block a property from appearing in the Properties window.

  • Category Enables you to specify the category associated with the property. The property appears under this category in the Properties window.

  • DefaultValue Enables you to specify a default value for the property. When you right-click a property in the Properties window, you can select Reset to the return the property to its default value.

  • Description Enables you to specify the description associated with the property. The description appears in the Properties window when the property is selected.

  • DesignerSerializationVisibility Enables you to specify how changes to a property are serialized. Possible values are Visible, Hidden, and Content.

  • Editor Enables you to specify a custom editor for editing the property in Design view.

  • EditorBrowsable Enables you to block a property from appearing in Intellisense.

  • NotifyParentProperty Enables you to specify that changes to a subproperty should be propagated to the parent property.

  • PersistenceMode Enables you to specify whether a property is persisted as a control attribute or control content. Possible values are Attribute, EncodedInnerDefaultProperty, InnerDefaultProperty, and InnerProperty.

  • TypeConverter Enables you to associate a custom type converter with a property. A type converter converts a property between a string representation and a type (or vice versa).

The Editor attribute enables you to associate a particular editor with a property. Certain types in the Framework have default editors. For example, a property which represents a System.Drawing.Color value is automatically associated with the ColorEditor. The ColorEditor displays a color picker (see Figure 31.14). To view the list of editors included in the .NET Framework, look up the UITypeEditor class in the .NET Framework SDK Documentation.

Figure 31.14. Using the ColorEditor to pick a color.


The MovieView control contained in Listing 31.32 illustrates how you can use several of these attributes. The control displays a single movie.

Listing 31.32. MovieView.vb

Imports System Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.ComponentModel Namespace myControls     <DefaultProperty("Title")> _     Public Class MovieView         Inherits WebControl         Private _title As String = "Movie Title"         Private _description As String = "Movie Description"         <Category("Movie")> _         <Description("Movie Title")> _         Public Property Title() As String             Get                 Return _title             End Get             Set(ByVal Value As String)                 _title = Value             End Set         End Property         <Category("Movie")> _         <Description("Movie Description")> _         Public Property Description() As String             Get                 Return _description             End Get             Set(ByVal Value As String)                 _description = Value             End Set         End Property         Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)             writer.RenderBeginTag(HtmlTextWriterTag.H1)             writer.Write(_title)             writer.RenderEndTag()             writer.Write(_description)         End Sub         Protected Overrides ReadOnly Property TagKey() As HtmlTextWriterTag             Get                 Return HtmlTextWriterTag.Div             End Get         End Property     End Class End Namespace 

The page in Listing 31.33 contains the MovieView control. Open the page in Design view to see the effect of the various design-time attributes. For example, notice that a category and description are associated with both the Title and Description properties in the Properties window (see Figure 31.15).

Figure 31.15. The MovieView control in Design view.


Listing 31.33. ShowMovieView.aspx

[View full width]

<%@ Page Language="VB" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!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>Show MovieView</title> </head> <body>     <form  runat="server">     <div>     <custom:MovieView                  Runat="server" />     </div>     </form> </body> </html> 

Creating Control Designers

You can modify the appearance of your custom controls in Design view by creating a ControlDesigner. The ASP.NET 2.0 Framework enables you to implement a number of fancy features when you implement a ControlDesigner. This section focuses on just two of these advanced features.

First, you learn how to create a ContainerControlDesigner. A ContainerControlDesigner enables you to drag and drop other controls from the Toolbox onto your control in Design view.

You also learn how to add Smart Tags (also called Action Lists) to your control. When a control supports Smart Tags, a menu of common tasks pop up above the control in Design view.

Creating a Container ControlDesigner

If you associate a custom control with a ContainerControlDesigner, then you can add child controls to your control in Design view. For example, the file in Listing 31.34 contains a GradientPanel control. This control displays a gradient background behind its contents (see Figure 31.16).

Figure 31.16. Displaying the GradientPanel control.


Listing 31.34. GradientPanel.vb

[View full width]

Imports System Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.Design Imports System.ComponentModel Imports System.Drawing Namespace myControls     <Designer(GetType(GradientPanelDesigner))> _     <ParseChildren(False)> _     Public Class GradientPanel         Inherits WebControl         Private _direction As GradientDirection = GradientDirection.Horizontal         Private _startColor As Color = Color.DarkBlue         Private _endColor As Color = Color.White         Public Property Direction() As GradientDirection             Get                 Return _direction             End Get             Set(ByVal Value As GradientDirection)                 _direction = Value             End Set         End Property         Public Property StartColor() As Color             Get                 Return _startColor             End Get             Set(ByVal Value As Color)                 _startColor = Value             End Set         End Property         Public Property EndColor() As Color             Get                 Return _endColor             End Get             Set(ByVal Value As Color)                 _endColor = Value             End Set         End Property         Protected Overrides Sub AddAttributesToRender(ByVal writer As HtmlTextWriter)             writer.AddStyleAttribute(HtmlTextWriterStyle.Filter, Me.GetFilterString())             MyBase.AddAttributesToRender(writer)         End Sub         Public Function GetFilterString() As String             Return String.Format("progid:DXImageTransform.Microsoft.Gradient( gradientType={0},startColorStr={1},endColorStr={2})", _direction.ToString("d"),  ColorTranslator.ToHtml(_startColor), ColorTranslator.ToHtml(_endColor))         End Function         Public Sub New()             Me.Width = Unit.Parse("500px")         End Sub         Protected Overrides ReadOnly Property TagKey() As HtmlTextWriterTag             Get                 Return HtmlTextWriterTag.Div             End Get         End Property     End Class     Public Enum GradientDirection         Vertical = 0         Horizontal = 1     End Enum     Public Class GradientPanelDesigner         Inherits ContainerControlDesigner         Protected Overrides Sub AddDesignTimeCssAttributes(ByVal styleAttributes As System .Collections.IDictionary)             Dim gPanel As GradientPanel = CType(Me.Component, GradientPanel)             styleAttributes.Add("filter", gPanel.GetFilterString())             MyBase.AddDesignTimeCssAttributes(styleAttributes)         End Sub     End Class End Namespace 

The GradientPanel control uses an Internet Explorer filter to create the gradient background. The filter is applied in the AddAttributesToRender() method. You can set the StartColor, EndColor, and Direction properties to control the appearance of the gradient background.

Notice that the GradientPanel control is decorated with a ControlDesigner attribute. This attribute associates the GradientPanelDesigner class with the GradientPanel control.

The GradientPanelDesigner is also included in Listing 31.34. One method is overridden in the GradientPanelDesigner class. The AddDesignTimeCssAttributes() method is used to apply the gradient background in Design view.

Warning

The file in Listing 31.34 doesn't compile unless you add a reference to the System.Design.dll assembly to your application. You can add the necessary reference by selecting the menu option Website, Add Reference and selecting the System.Design assembly.


The page in Listing 31.35 illustrates how you can declare the GradientPanel in a page. However, to understand the effect of the ContainerControlDesigner, you need to open the page in Design view in either Visual Web Developer or Visual Studio .NET.

Listing 31.35. ShowGradientPanel.aspx

[View full width]

<%@ Page Language="VB" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!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>Show GradientPanel</title> </head> <body>     <form  runat="server">     <div>     <custom:GradientPanel                  Runat="server">         <asp:Calendar                          runat="server" />     </custom:GradientPanel>     </div>     </form> </body> </html> 

When you open the page in Listing 31.35 in Design view, you can drag other controls from the toolbox onto the GradientPanel control. For example, if you drag a Calendar control onto the GradientPanel control, the Calendar control is added automatically to the control collection of the GradientPanel (see Figure 31.17).

Figure 31.17. Editing the GradientPanel control in Design view.


Adding Smart Tasks

If you add a GridView control to a page when you are in Design view, you'll notice that a menu of common tasks appears above the GridView. For example, you can select a Smart Task to enable sorting or paging.

You can add your own Smart Tasks to a custom control by inheriting a new class from the base DesignerActionList class.

For example, the file in Listing 31.36 contains three classes. It contains a custom control, named the SmartImage control, which enables you to rotate and mirror images. It also contains a ControlDesigner. Finally, it contains a DesignerActionList class that contains two Smart Tasks.

Listing 31.36. SmartImage.vb

[View full width]

Imports System Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.Design Imports System.ComponentModel Imports System.ComponentModel.Design Namespace myControls     <Designer(GetType(SmartImageDesigner))> _     Public Class SmartImage         Inherits WebControl         Private _imageUrl As String         Private _alternateText As String         Private _rotation As Integer = 0         Private _mirror As Boolean = False         Public Property ImageUrl() As String             Get                 Return _imageUrl             End Get             Set(ByVal Value As String)                 _imageUrl = Value             End Set         End Property         Public Property AlternateText() As String             Get                 Return _alternateText             End Get             Set(ByVal Value As String)                 _alternateText = Value             End Set         End Property         Public Property Rotation() As Integer             Get                 Return _rotation             End Get             Set(ByVal Value As Integer)                 _rotation = Value             End Set         End Property         Public Property Mirror() As Boolean             Get                 Return _mirror             End Get             Set(ByVal Value As Boolean)                 _mirror = Value             End Set         End Property         Protected Overrides ReadOnly Property TagKey() As HtmlTextWriterTag             Get                 Return HtmlTextWriterTag.Img             End Get         End Property         Private Function GetFilterString() As String             Dim _mirrorValue As String = "0"             If _mirror Then                 _mirrorValue = "1"             End If             Return String.Format("progid:DXImageTransform.Microsoft.BasicImage(Rotation={0 },Mirror={1})", _rotation, _mirrorValue)         End Function         Protected Overrides Sub AddAttributesToRender(ByVal writer As HtmlTextWriter)             writer.AddStyleAttribute(HtmlTextWriterStyle.Filter, Me.GetFilterString())             writer.AddAttribute(HtmlTextWriterAttribute.Src, _imageUrl)             writer.AddAttribute(HtmlTextWriterAttribute.Alt, _alternateText)             MyBase.AddAttributesToRender(writer)         End Sub     End Class     Public Class SmartImageDesigner         Inherits ControlDesigner         Public Overrides ReadOnly Property ActionLists() As DesignerActionListCollection             Get                 Dim colActions As New DesignerActionListCollection()                 colActions.AddRange(MyBase.ActionLists)                 colActions.Add(New SmartImageActionList(Me))                 Return colActions             End Get         End Property     End Class     Public Class SmartImageActionList         Inherits DesignerActionList         Private items As DesignerActionItemCollection         Private _parent As SmartImageDesigner         Public Sub New(ByVal parent As SmartImageDesigner)             MyBase.New(parent.Component)             _parent = parent         End Sub         Public Sub Rotate()             Dim toCall As TransactedChangeCallback = New TransactedChangeCallback (AddressOf DoRotate)             ControlDesigner.InvokeTransactedChange(Me.Component, toCall, "Rotate", "Rotate  image 90 degrees")         End Sub         Public Sub Mirror()             Dim toCall As TransactedChangeCallback = New TransactedChangeCallback (AddressOf DoMirror)             ControlDesigner.InvokeTransactedChange(Me.Component, toCall, "Mirror", "Mirror  Image")         End Sub         Public Overrides Function GetSortedActionItems() As DesignerActionItemCollection             If IsNothing(items) Then                 items = New DesignerActionItemCollection()                 items.Add(New DesignerActionMethodItem(Me, "Rotate", "Rotate Image", True))                 items.Add(New DesignerActionMethodItem(Me, "Mirror", "Mirror Image", True))             End If             Return items         End Function         Public Function DoRotate(ByVal arg As Object) As Boolean             Dim img As SmartImage = CType(Me.Component, SmartImage)             img.Rotation += 1             If img.Rotation > 3 Then                 img.Rotation = 0             End If             _parent.UpdateDesignTimeHtml()             Return True         End Function         Public Function DoMirror(ByVal arg As Object) As Boolean             Dim img As SmartImage = CType(Me.Component, SmartImage)             img.Mirror = Not img.Mirror             _parent.UpdateDesignTimeHtml()             Return True         End Function     End Class End Namespace 

The SmartImage control takes advantage of an Internet Explorer filter named the BasicImage filter. This filter enables you to manipulate images by rotating, mirroring, and changing the opacity of images. In Listing 31.36, the filter is applied in the AddAttributesToRender() method.

The SmartImage control is associated with a ControlDesigner named the SmartImageDesigner through the control's Designer attribute. The SmartImageDesigner class overrides the base class's ActionLists property to expose a custom DesignerActionList.

The DesignerActionList is the final class declared in Listing 31.36. This class contains four methods named Rotate(), DoRotate(), Mirror(), and DoMirror(). The GetSortedActionItems() method exposes the Rotate and Mirror actions.

When all is said and done, the custom ActionList enables you to display Rotate and Mirror Smart Tags for the SmartImage control in Design view. When you click the Rotate action in Design view, the SmartImage does in fact rotate (see Figure 31.18).

Figure 31.18. Adding Smart Tags to a control.


Note

You can view the SmartImage control by opening the ShowSmartImage.aspx page included on the CD that accompanies this book.





ASP. NET 2.0 Unleashed
ASP.NET 2.0 Unleashed
ISBN: 0672328232
EAN: 2147483647
Year: 2006
Pages: 276

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net