|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionHave you ever wanted to build a custom web control, but lost confidence once you started to navigate the MSDN information ocean? Ever wanted to build a web control only to find out that you don't know where to start and worse yet there are no comprehensive examples available on the internet? If you have faced any or all of these situations, sit back and relax! Throughout this article I will detail the major "gotchas" relating to building a custom web control and deploy it to your web application. About Web ControlsWeb Controls should be designed with the following considerations in mind; alleviate repetitive, complex tasks and add new functionality to your web pages (web forms). After wading through numerous resources, I discovered that .NET controls for the web can come in many different varieties! In short, web controls can be broken down into 6 logical types (classes):
Since we are going to focus on custom controls, I will limit discussion on all other types to a basic definition. Web Controls DefinedHTML Server Controls: HTML Server Controls are HTML elements containing attributes which make them visible to, and programmable on the web server. Additionally, HTML Controls map closely to HTML elements via public properties and styles. Web Server Control: Web Server Controls are designed to provide a quick, easy way to add functionality to your web pages. These controls provide for up and down level browser support. The core requirements for Up-level Browsers are; ECMAScript (JScript, JavaScript) support, HTML version 4.0 compliance, Supports Microsoft Document Object Model (MSDOM) and Cascading style sheets (CSS) support. Additionally, these controls can be used to build more complex server controls. Web Validation Control: Validation controls provide you with a way to check user input in Web or HTML server controls. Attach validation controls to input controls to test what the user enters for that input control. Web User Control: Web User Controls are created like Web Forms pages. These controls can be embedded into other Web Forms pages and are an easy way to create menus, toolbars, and other reusable elements. These types of controls always end with the extension of .ascx and must be included separately in each project that uses the control. Web User Controls are dynamically compiled at run time. Composite Control: Composite Controls combine the functionality of two or more existing controls and can expose custom properties and events. Basic requirements for implementation: must override the CreateChildControls method inherited from Control and must implement System.Web.UI.INamingContainer interface for unique naming convention. Custom Control: Custom Controls are fully authored, pre-compiled code (.dll) and are a good choice for dynamic web page layout. The major advantage of Custom Controls is full design-time support, to include: Toolbox Integration, Visual Designers support and interfacing with the Property Grid. These controls can be installed to the Global Assembly Cache (GAC) which will allow multiple applications to share a single control. Classy Choices - enter System.Web.UI
The The two classes that we will focus on for the purpose of this article are The The behavior of the control can be specified by setting certain properties. You can enable and disable a control by setting the Enabled property. The place of the control in the tab order is controlled by setting the TabIndex property. You can specify a ToolTip for the control by setting the ToolTip property. Enough Already! How does it work?Now that all the basics are out of the way, lets examine the class I implemented for <DefaultProperty("Type"), _
ToolboxData("<{0}:WebChart runat="server"></{0}:WEBCHART>"), _
ParseChildren(True, "WebChartItems"), ToolboxBitmapAttribute(GetType(Bitmap))> _
Public Class WebChart : Inherits System.Web.UI.WebControls.WebControl
...
End Class
The above code block is relatively easy to understand, but what's all the stuff above the class statement? These are known as attributes. When you compile your code for the runtime, it is converted into Microsoft intermediate language (MSIL) and placed inside a portable executable (PE) file along with metadata generated by the compiler. Attributes allow you to place extra descriptive information into metadata that can be extracted using runtime reflection services. The compiler creates attributes when you declare instances of special classes that derive from System.Attribute. The ToolBoxData Attribute specifies how the control will be named when placed on an ASP.NET web form. The ParseChildren Attribute must identify the indexed property you will hold your collection within. The ToolboxBitmap Attribute is used to supply a custom icon for your control. The icon must be 16 x 16 and be restricted to 16 colors. The bottom left corner of the bitmap is used as the transparency color. Lastly, the icon for this project is set as an embedded resource and is named the same as the Root Namespace. Public Enum ChartType
Pie = 0
Bar = 1
End Enum
...
'Chart layout fields
Private mChartType As ChartType = ChartType.Bar
'Scalar Property
<DefaultValue(GetType(ChartType), "Bar"), Category("Chart Common"), _
Description("Type of chart to generate.")> _
Public Property Type() As ChartType
Get
Return mChartType
End Get
Set(ByVal Value As ChartType)
mChartType = Value
End Set
End Property
Scalar Property (above): Notice that the public property Type is declared as the type ChartType. This will allow the Property Type to contain a drop down box populated with the 'English' values to be displayed in the property grid. Also, by initializing the mChartType property to ChartType = ChartType.Bar you are effectively assigning a default value to your property! The Attribute DefaultValue is set to get the type ChartType via Reflection and set the value to "Bar". In the property grid default values are not bolded, values which have changed from their default property will be displayed as bold text. The Category Attribute determines which category this property will be associated with on the PropertyGrid. Last, the Description Attribute is used to give the developer an idea of what the property does. <DefaultProperty("Type"), _
ToolboxData("<{0}:WebChart runat="server"></{0}:WEBCHART>"), _
ParseChildren(True, "WebChartItems"), ToolboxBitmapAttribute(GetType(Bitmap))> _
Public Class WebChart : Inherits System.Web.UI.WebControls.WebControl
'Chart data fields - All Types
Private mWebChartItems As New WebChartItemCollection(Me)
'Indexed Property
<Category("Chart Common"), _
DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
PersistenceMode(PersistenceMode.InnerDefaultProperty), _
Description("Supply data values for selected chart.")> _
Public ReadOnly Property WebChartItems() As WebChartItemCollection
Get
If mWebChartItems Is Nothing Then
mWebChartItems = New WebChartItemCollection(Me)
End If
Return mWebChartItems
End Get
End Property
'This Class Handles WebChart Collection
<Serializable()> _
Public Class WebChartItemCollection : _
Inherits System.Collections.CollectionBase
Private mOwner As WebChart
Public Sub New()
MyBase.New()
End Sub
Public Sub New(ByVal Owner As WebChart)
MyBase.New()
mOwner = Owner
End Sub
Private Property Owner() As WebChart
Get
Return CType(mOwner, WebChart)
End Get
Set(ByVal Value As WebChart)
mOwner = Value
End Set
End Property
Default Public ReadOnly Property Item(ByVal index As Int32) As WebChartItem
Get
Return CType(List.Item(index), WebChartItem)
End Get
End Property
Public Function Add(ByVal Item As WebChartItem) As Integer
Return List.Add(Item)
End Function
End Class
End Class
Indexed Property: Our indexed property WebChartItems is ReadOnly because it only controls the return of our collection object. Keep in mind that a Adding WebChart to the ToolboxIn order to use the Example useAdding the control at design-time is straight forward, use it like any of the native ASP.NET Controls. However, you must insert the following XML tags into your Web.config file directly underneath the opening <SYSTEM.WEB> tag (see below). This tag allows ASP.NET to track WebChart images via Application Variable. The <httpModules> tag is required for proper WebChart operation. The following code block shows how to create a pie type REQUIRED: Place the following httpModules XML in your local Web.config. <SYSTEM.WEB> Imports System.Data.SqlClient
Imports blong.WebControls
Protected Sub MakeChart()
' Define Objects
Dim Chart As WebChart
Dim i As Int32
Dim cn As New SqlConnection(Session.Item("strConn"))
Dim cmd As New SqlCommand("WebHitsPerMonth", cn)
Dim dReader As SqlDataReader
cn.Open()
cmd.CommandType = CommandType.StoredProcedure
dReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
' Override Default Constructor
' Copyright Symbol: Hold ALT + 0681
Chart = New WebChart()
With Chart
.ID = "CodeChart"
.Type = WebChart.ChartType.Pie
' Override WebChartItems for Pie Data
Dim highVal As Single
Dim ExplodeIndex As Int32
While dReader.Read
If Not IsDBNull(dReader("HitYear")) Then
.WebChartItems.Add(New WebChartItem(dReader("HitMonth") & _
" " & dReader("HitYear"), dReader("HitMonthCount"), False))
If dReader("HitMonthCount") > highVal Then
highVal = dReader("HitMonthCount")
ExplodeIndex = i - 1
End If
End If
i += 1
End While
'Explode High Value
.WebChartItems(ExplodeIndex).Explode = True
.ShowLegend = True
.Diameter = WebChart.PieDiameter.Larger
.ExplodeOffset = 25
.Rotate = 70
.Thickness = WebChart.PieThickness.Medium
.Title = "My Run Time Chart"
'Specify output format
.Format = WebChart.ChartFormat.Png
End With
' Add control to web form
Me.Controls.Add(Chart)
End Sub
WebChart CreditsSpecial thanks to Mohammed Banat at eSense Software, Development and Consulting, for help on HTTP streaming which allows WebChart to draw charts directly to the Output.Response stream with no additional external web pages. WebChart History
| ||||||||||||||||||||