Introduction

My background as a Geographer/GIS guru often involves developing web sites for interactive mapping on a variety of topics. One of our requirements include abilities to create vector graphics on the client side for functions such as zoom boxes, measurement tools, shapes (points, lines, polygons), and other things common to desktop Geographical Information Systems. Many of our clients have strict guidelines that include developing applications which do not require plug-ins and/or downloads. I have found VML to be a perfect solution for this requirement and have developed VML drawing controls to enable drag and drop tools for the creation of client side line, polyline, polygon, rectangle and round rectangle graphics to automate this task. In this article, we will take a look at the VMLControl base class and then the VMLPolygon web control as an example of these VML drawing controls.

* Please note, although there are no downloads or plug-ins required, an Internet Explorer web browser is.

Using the code

These controls should be used like any other .NET web control and can be added to your project through the Add/Remove Toolbox Items... under the Tools menu in the Visual Studio IDE.

The VMLDrawingControls comprises of five shape control classes that are derived from the VMLControl base class.

VMLLine

VMLPolyline

VMLPolygon

VMLRectangle

VMLRoundRectangle (inherits from VMLRectangle)

VMLControl

The MustInheritVMLControl base class provides the framework for the controls and includes properties for:

ID

ButtonType [Button | Image]

ButtonText

ImageSrc, ImageSrcMouseDown, ImageSourceMouseOver

CursorStyle, CustomCursor, CustomCursorEnabled

BoundingDrawCanvas

The BoundingDrawCanvas is the required property which holds the ID of the image control that will be used as the bounding drawing canvas for the vector graphics. I used the AddAttributesToRender overrides of the System.Web.UI.WebControls.WebControl to warn the user of this requirement. Once the requirement has been met in the control's properties, the warning will go away.

I created a BoundingControlsConverter for this property to list out the current image controls on the web form. Due to the nature of my work, I use the image web control (which contains my map image) as my drawing canvas. The GetStandardValues override from the base class System.ComponentModel.TypeConverter allows me to retrieve the IDs of the image controls for the property dropdown list. Using the Context.Container.Components passed in, allows me to loop the components of the page to identify image controls to use for the canvas. A future modification will be to accommodate table cells, divs, and other container tags.

VML Styles

I created three VML style classes that were used as properties for the drawing control classes to define things like color, width, style, fill patterns, etc.

VMLLineStyle

VMLFillStyle

LineEndPointProperties (provides From and To point styles)

For example, the VMLPolygon control has the FillStyle property of type VMLFillStyle which defines the color, pattern, etc. for the polygon to be rendered. The ExpandableObjectConverter was used to make the property expandable in the property grid similar to the Font property of other controls.

A module named HelperFunctions was created to extend these controls. The ReadJavascript procedure was created to read the JavaScript source file to manipulate the VML graphics on the client side as a resource of the assembly and the contents written to the out-stream. Using this method, I can keep all of the JavaScript in a single .js file and modify it as needed and then simply rebuild the assembly. There is also a property in the VMLControl base class which I added to reference an external .js file but never thoroughly implemented it.

VMLPolygon

The VMLPolygon is an example of the VMLDrawingControls. This controls inherits from the VMLControl base class and has methods and properties to define the look and feel of the rendered polygon. As shown above, the control uses the VMLFillStyle to define the fill properties and it all uses the VMLLineStyle to define the outline properties of the polygon.

Putting It All Together

With the properties assigned, we can use the RenderChildren of our shape classes to write out the VML tags to the browser. The ID assigned in the control properties is used by the client-side script to dynamically modify the VML shape properties.

Points of Interest

One of the issues I ran into while creating these controls is the ability or inability to persist the control properties to the designer. I found the Visual Studio IDE to sometime not update or persist these properties during the building phases of these controls and seemed to resolve itself upon a restart of the IDE. I believe these problems to be resolved with newer releases of the IDE.

Future Enhancements

I hope to enhance these controls in the future to have a VML control for general shape, text, arc, oval, image and other VML elements. I would also like to implement a method for returning the coordinates of the shapes to the server for special processing needs.

History

Original posting -- Dec 15, 2005

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Comments and Discussions

Hi,thanks for interesting and great job done.
I would be specially interested in applying the VML graphics from the server-side as well as using feedback information from your control for further processing. Any time plan for these functionalities?
Is there possibility to render text in the same way as other VML elements?

I am a bit busy the month of Jan. with real work but plan to add the server coordinate return functionality in Feb. with some new VML elements. I have started some of the text element functionality already but a lot of work needs to be done for placement options. If you are a developer and wish to add to these controls yourself let me know and I will include your code in the article update.