VML网页控件

分享于 

21分钟阅读

Web开发

  繁體

VML Drawing Controls

介绍

作为 geographer/gis专家的background 通常需要开发用于在各种主题上进行交互式映射的网站。 我们的一个需求包括在客户端创建矢量图形,比如缩放框。测量工具。形状(。点,线,多边形) 等等。 我们的许多客户都有严格的指南,包括开发不需要 Plug-Ins 和/或者下载的应用程序。 为了使客户端直线,多段线,多边形,rectangle 和圆形 rectangle 图形自动生成,我发现VML是一个完美的解决方案,并已经开发了用于创建客户端线条的工具。 在本文中,我们将看一下 VMLControl 基类,然后将 VMLPolygon web控件作为这些of控件的示例。

* 请注意,虽然没有下载或者 Plug-Ins 需要,但是 IE web浏览器。

背景

有关VML的更多信息,请参见 StewartStewart Simon StewartStewart和微软VML参考文档的 我还想扩展一下 Sreenivas Vemulapalli,它的文章使用了属性网格插件,帮助这些控件对这些控件进行了。

VML命名空间引用:VML的用法需要在HTML文档中包含以下标记用法:

<HTMLxmlns:v="urn:schemas-microsoft-com:vml"><HEAD><style>v:* { BEHAVIOR: url(#default#VML) } </style>
 </HEAD>. . ..

使用代码

可以像其他. NET web控件一样使用这些控件,并且可以通过添加/移除工具箱项添加到项目中。 在 Visual Studio IDE的工具菜单下。

VMLDrawingControls由由 VMLControl 基类派生的五个shape控件类组成。

  • VMLLine
  • VMLPolyline
  • VMLPolygon
  • VMLRectangle
  • VMLRoundRectangle ( 从 VMLRectangle 继承)

VML Designer Controls

VMLControl

iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 MustInheritVMLControl 基类提供控件的框架,并包含以下属性:

  • ID
  • ButtonType [ Button | Image ]
  • ButtonText
  • ImageSrcImageSrcMouseDownImageSourceMouseOver
  • CursorStyleCustomCursorCustomCursorEnabled
  • BoundingDrawCanvas

BoundingDrawCanvas 是必需属性,它保存将用作矢量图形的边界绘图画布的图像控件的ID。 我使用了 AddAttributesToRenderSystem.Web.UI.WebControls.WebControl 向用户发出这里要求的警告。 一旦控制的属性达到了要求,警告就会消失。

ProtectedOverridesSub AddAttributesToRender(ByVal _
 output As System.Web.UI.HtmlTextWriter)
 'Warn User Of Control RequirementsIfMe.BoundingDrawCanvas = ""Or _
 Me.BoundingDrawCanvas = "(none)"Then output.Write("<BR>")
 output.Write("<Font color='Red'>" & _ 
 "<li>BoundingDrawCanvas Property Is Required</Font>")
 ElseIf Page.FindControl(Me.BoundingDrawCanvas) IsNothingThen output.Write("<BR>")
 output.Write("<Font color='Red'>" & _ 
 "<li>BoundingDrawCanvas Control ID" & _ 
 " Cannot Be Found</Font>")
 EndIfEndIfMyBase.AddAttributesToRender(output)EndSub

* 代码源:VMLControl.vb

BoundingDrawCanvas Warning

下面是 VMLControl 基类中用于所有派生VML形状类的BoundingDrawCanvas 属性。

<Category("Appearance"), _
Description("The Control ID Of The Image Control" & _ 
 " Which Defines The Bounding Draw Canvas"), _
TypeConverter(GetType(BoundingControlsConverter)), _
PersistenceMode(PersistenceMode.Attribute)> _PublicProperty BoundingDrawCanvas() AsStringGet _BoundingDrawCanvas = _
 CType(ViewState("VMLBoundingDrawCanvas"), String)
 If _BoundingDrawCanvas IsNothingThenReturn"(none)"ElseReturn _BoundingDrawCanvas
 EndIfEndGetSet(ByVal Value AsString)
 ViewState("VMLBoundingDrawCanvas") = Value
 _BoundingDrawCanvas = Value
 EndSetEndProperty

*Code 源:VMLControl.vb

为此属性创建了一个 BoundingControlsConverter,以便列出网站窗体上的当前图像控件。 由于我的工作特性,我使用图像网页控件( 它包含我的地图图像) 作为绘图画布。 来自基类的GetStandardValues 重写 System.ComponentModel.TypeConverter 允许我检索属性下拉列表的图像控件的id。 使用传入的Context.Container.Components,允许我循环访问页面的组件以标识用于画布的图像控件。 未来的修改将是适应 table 细胞 div s,以及其他容器标记。

PublicOverloadsOverridesFunction GetStandardValues(ByVal context As _
 System.ComponentModel.ITypeDescriptorContext) As _
 System.ComponentModel.TypeConverter.StandardValuesCollection
 Dim supportedCtrls AsNew ArrayList
 Dim Component As IComponent
 'Supported Control TypesDim wcImg As WebControls.Image
 ForEach Component In context.Container.Components
 IfTypeOf Component Is WebControls.Image Then wcImg = CType(Component, WebControls.Image)
 supportedCtrls.Add(wcImg.ID)
 EndIfNext'Sort the list supportedCtrls.Sort()
 'return values to be listed in the property browser's dropdown listDim svc AsNew _
 StandardValuesCollection(CType(supportedCtrls.ToArray(GetType(String)), _
 String()))
 Return svcEndFunction

*Code 源:BoundingControlsConverter.vb

VML样式

我创建了三种,类,用作绘图控件类的属性,用于定义颜色。宽度。样式。填充模式等。

  • VMLLineStyle
  • VMLFillStyle
  • LineEndPointProperties ( 提供 FromTo 点样式)

VML Style Properties

例如 VMLPolygon 控件的FillStyle 属性为 VMLFillStyle 属性,它定义要呈现的多边形的颜色。Pattern。等等。 ExpandableObjectConverter 用于使属性在属性网格中可以扩展,类似于其他控件的Font 属性。

<Category("VML Symbolization"), _
Description("Defines The VML Fill Style Properties To Be Used"), _
DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
TypeConverter(GetType(ExpandableObjectConverter))> _PublicProperty FillStyle() As VMLFillStyle
 GetReturn _FillStyle
 EndGetSet(ByVal Value As VMLFillStyle)
 _FillStyle = Value
 EndSetEndProperty

*Code 源:VMLPolygon.vb

这是 VMLFillStyle 类:

Imports System.ComponentModelImports System.Web.UIImports System.Drawing.Design
<Serializable(), PersistenceMode(PersistenceMode.Attribute)> _PublicClass VMLFillStyle
 Enum FillTypeEnum
 Solid
 Gradient
 GradientRadial
 Tile
 Pattern
 Frame
 EndEnumPrivate _FillType As FillTypeEnum = FillTypeEnum.Solid
 Private _FillColor As System.Drawing.Color = NothingPrivate _FillColor2 As System.Drawing.Color = NothingPrivate _FillOpacity AsInt16 = 100Private _FillOpacity2 AsInt16 = 100SubNew()
 'Class ConstructorEndSub <Category("Rectangle Fill Appearance"), _
 Description("Defines The Type Of Fill To Apply"), _
 NotifyParentProperty(True)> _
 PublicProperty FillType() As FillTypeEnum
 GetReturn _FillType
 EndGetSet(ByVal Value As FillTypeEnum)
 _FillType = Value
 EndSetEndProperty <Category("Rectangle Fill Appearance"), _
 Description("Defines The Primary Fill Color"), _
 NotifyParentProperty(True)> _
 Property FillColor() As System.Drawing.Color
 GetReturn _FillColor
 EndGetSet(ByVal Value As System.Drawing.Color)
 _FillColor = Value
 EndSetEndProperty <Category("Rectangle Fill Appearance"), _
 Description("Defines The Secondary Fill Color"), _
 NotifyParentProperty(True)> _
 Property FillColor2() As System.Drawing.Color
 GetReturn _FillColor2
 EndGetSet(ByVal Value As System.Drawing.Color)
 _FillColor2 = Value
 EndSetEndProperty <Category("Rectangle Fill Appearance"), _
 Description("Defines The Opacity Of The Primary Color"), _
 NotifyParentProperty(True)> _
 Property FillOpacity() AsInt16GetReturn _FillOpacity
 EndGetSet(ByVal Value AsInt16)
 If ((Value <0Or Value> 100)) ThenThrowNew ArgumentException("The Opacity" & _ 
 " Must Be Beteen 0 and 100")
 EndIf _FillOpacity = Value
 EndSetEndProperty <Category("Rectangle Fill Appearance"), _
 Description("Defines The Opacity Of The Secondary Color"), _
 NotifyParentProperty(True)> _
 Property FillOpacity2() AsInt16GetReturn _FillOpacity2
 EndGetSet(ByVal Value AsInt16)
 If ((Value <0Or Value> 100)) ThenThrowNew ArgumentException("The Opacity2" & _ 
 " Must Be Beteen 0 and 100")
 EndIf _FillOpacity2 = Value
 EndSetEndProperty <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
 PublicReadOnlyProperty FillTag() AsStringGetDim retFillTag AsNew System.Text.StringBuilder
 retFillTag.Append("<v:fill")
 retFillTag.Append(" Type=" & Quote(Me.FillType.ToString))
 retFillTag.Append(" Color=" & _
 Quote(HelperFunctions.BuildRGBString(Me.FillColor)))
 retFillTag.Append(" Color2=" & _
 Quote(HelperFunctions.BuildRGBString(Me.FillColor2)))
 retFillTag.Append(" Opacity=" & _
 Quote(FillOpacity.ToString & "%"))
 retFillTag.Append(" Opacity2=" & _
 Quote(Me.FillOpacity2.ToString & "%"))
 retFillTag.Append("/>")
 Return retFillTag.ToString
 EndGetEndProperty <Description("Define The VML Fill Properties")> _
 OverridesFunction ToString() AsStringReturn"(VML Fill Style)"EndFunctionEndClass

*Code 源:VMLFillStyle.vb

创建了名为 HelperFunctions的MODULE 来扩展这些控件。 ReadJavascript 过程被创建以读取JavaScript源文件,以便作为程序集的资源以及写入流的资源操作。 在使用这里方法时,我可以将所有的JavaScript保存在单个. js 文件中,并根据需要修改它,然后简单地重新生成程序集。 在 VMLControl 基类中还有一个属性,我添加到引用外部. js 文件,但从未彻底实现它。

PublicFunction ReadJavasript() AsStringDim jsStream As IO.Stream
 jsStream = System.Reflection.Assembly.GetExecutingAssembly()._
 GetManifestResourceStream("VMLDrawingControls" & _ 
 ".VMLClientJavascript.js")
 Dim jsStreamReader AsNew StreamReader(jsStream)
 Return jsStreamReader.ReadToEndEndFunction

*Code 源:HelperFunctions.vb

ProtectedOverridesSub Render(ByVal output As _
 System.Web.UI.HtmlTextWriter)
 'Stream the Javascript Page.RegisterStartupScript("VMLScript", _
 "<script language=""javascript"">" & _
 HelperFunctions.ReadJavasript & " </script>")
 MyBase.Render(output)EndSub

*Code 源:VMLPolygon.vb

VMLPolygon

VMLPolygonVMLDrawingControls的一个例子。 这里控件从 VMLControl 基类继承,并具有定义已经渲染多边形的外观和感觉的方法和属性。 如 上面 所示,控件使用 VMLFillStyle 定义填充属性,并且它们都使用 VMLLineStyle 定义多边形的大纲属性。

Imports System.web.UI.HtmlTextWriterImports System.Web.UIImports System.Web.UI.DesignImports System.ComponentModelImports System.Drawing.DesignImports System.DrawingImports System.DesignImports System.Windows.Forms
<Designer(GetType(VMLControlDesigner)), _
ToolboxData("<{0}:VMLPolygon runat="server"></{0}:VMLPolygon>")> _PublicClass VMLPolygon
 Inherits VMLControl
 Implements INamingContainer
 SubNew()
 MyBase.ButtonText = "Draw Polygon"EndSubPrivate _LineStyle AsNew VMLLineStyle
 Private _FillStyleEnabled AsBoolean = FalsePrivate _FillStyle AsNew VMLFillStyle
 <Category("Appearance"), _
 Description("Defines The Line Stroke Style"), _
 DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
 TypeConverter(GetType(ExpandableObjectConverter))> _
 PublicProperty LineStyle() As VMLLineStyle
 GetReturn _LineStyle
 EndGetSet(ByVal Value As VMLLineStyle)
 _LineStyle = Value
 EndSetEndProperty <Category("VML Symbolization"), _
 Description("Enables The Use Of A FillStyle")> _
 PublicProperty FillStyleEnabled() AsBooleanGetReturn _FillStyleEnabled
 EndGetSet(ByVal Value AsBoolean)
 _FillStyleEnabled = Value
 EndSetEndProperty <Category("VML Symbolization"), _
 Description("Defines The VML Fill Style Properties To Be Used"), _
 DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
 TypeConverter(GetType(ExpandableObjectConverter))> _
 PublicProperty FillStyle() As VMLFillStyle
 GetReturn _FillStyle
 EndGetSet(ByVal Value As VMLFillStyle)
 _FillStyle = Value
 EndSetEndPropertyProtectedOverridesSub Render(ByVal output As _
 System.Web.UI.HtmlTextWriter)
 'Stream the Javascript Page.RegisterStartupScript("VMLScript", _
 "<script language=""javascript"">" & _
 HelperFunctions.ReadJavasript & " </script>")
 MyBase.Render(output)
 EndSubProtectedOverridesSub AddAttributesToRender(ByVal output _
 As System.Web.UI.HtmlTextWriter)
 Dim cursorString AsStringIfMe.CustomCursorEnabled Then cursorString = "url(" & Me.CustomCursor.ToString.ToLower & ")"Else cursorString = Me.CursorStyle.ToString
 EndIfSelectCaseMe.ButtonType
 Case ButtonTypeEnum.Button
 output.AddAttribute(HtmlTextWriterAttribute.Type, "button")
 output.AddAttribute(HtmlTextWriterAttribute.Onclick, _
 "activate('" & Me.ID & "','" & Me.BoundingDrawCanvas & _
 "','POLYGON','" & cursorString & "')")
 output.AddAttribute(HtmlTextWriterAttribute.Value, Me.ButtonText)
 Case ButtonTypeEnum.Image
 output.AddAttribute(HtmlTextWriterAttribute.Type, "image")
 output.AddAttribute(HtmlTextWriterAttribute.Onclick, _
 "activate('" & Me.ID & "','" & Me.BoundingDrawCanvas & _
 "','POLYGON','" & cursorString & "'); return false;")
 output.AddAttribute(HtmlTextWriterAttribute.Src, _
 Me.ImageSrc.Replace("", "/"))
 output.AddAttribute("onmouseout", "this.src='" & _
 Me.ImageSrc.Replace("", "/") & "';")
 'Add Mouseover & MouseDown ImagesIfNotMe.ImageSrcMouseOver.Equals(String.Empty) Then output.AddAttribute("onmouseover", "this.src='" & _
 Me.ImageSrcMouseOver.Replace("", "/") & "';")
 EndIfIfNotMe.ImageSrcMouseDown.Equals(String.Empty) Then output.AddAttribute("onmousedown", _
 "return false; this.src='" & _
 Me.ImageSrcMouseDown.Replace("", "/") & "';")
 EndIfEndSelectMyBase.AddAttributesToRender(output)
 EndSubProtectedOverridesSub RenderChildren(ByVal output As _
 System.Web.UI.HtmlTextWriter)
 'Create The VML TagDim outTags AsNew System.Text.StringBuilder
 outTags.Append("<v:polyline ID=" & Quote(Me.ID) & "")
 Dim cursorString AsStringIfMe.CustomCursorEnabled Then cursorString = Me.CustomCursor
 outTags.Append("style=" & DoubleQuoteChar & _
 "z-index: 1002;cursor: url('" & _
 cursorString & "');" & DoubleQuoteChar & ">")
 Else cursorString = Me.CursorStyle.ToString
 outTags.Append("style='cursor:" & cursorString & ";z-index: 1002;'>")
 EndIf outTags.Append(Me.LineStyle.StrokeTag)
 IfMe.FillStyleEnabled Then outTags.Append(Me.FillStyle.FillTag)
 EndIf outTags.Append("</v:polyline>")
 output.Write(outTags.ToString)
 EndSubEndClass

*Code 源:VMLPolygon.vb

连接各个部分

指定属性后,我们可以使用形状类的RenderChildren 将VML标记写出到浏览器。 客户端脚本使用控件属性中分配的ID来动态修改VML形状属性。

ProtectedOverridesSub RenderChildren(ByVal output As System.Web.UI.HtmlTextWriter)
 'Create The VML TagDim outTags AsNew System.Text.StringBuilder
 outTags.Append("<v:polyline ID=" & Quote(Me.ID) & "")
 Dim cursorString AsStringIfMe.CustomCursorEnabled Then cursorString = Me.CustomCursor
 outTags.Append("style=" & DoubleQuoteChar & _
 "z-index: 1002;cursor: url('" & _
 cursorString & "');" & DoubleQuoteChar & ">")
 Else cursorString = Me.CursorStyle.ToString
 outTags.Append("style='cursor:" & _
 cursorString & ";z-index: 1002;'>")
 EndIf outTags.Append(Me.LineStyle.StrokeTag)
 IfMe.FillStyleEnabled Then outTags.Append(Me.FillStyle.FillTag)
 EndIf outTags.Append("</v:polyline>")
 output.Write(outTags.ToString)EndSub

*Code 源:VMLPolygon.vb

Points of Interest

创建这些控件时遇到的问题之一是,是否能够将控件属性持久化到设计器中。 在这些控件的构建阶段,我发现 Visual Studio IDE没有更新或者持久化这些属性,并且似乎在IDE的重启过程中自行解决。 我相信这些问题要用最新版本的IDE来解决。

未来的增强功能

我希望将来能够增强这些控件,为一般形状。文本。arc。椭圆。图像等等提供一个ioctl控件。 我还希望实现一种方法,用于将形状的坐标返回到服务器,以便特殊处理需求。

历史记录

  • 原始发布 -- 2005年月15日

相关文章