一、简介
本文描述一种创建定制web控件并应用于一个ASP.NET 2.0 web页面中显示微软DirectX图像转换过滤效果的容易的方法。文中包括一个拥有11个不同控件的类库,每一个控件分别展示微软DirectX图像转换过滤效果的某些方面。在这11个控件中,5个是页面过渡效果控件,其它的6个是用于增强文本外观的过滤效果控件。
在这6个用于增强文本外观的过滤效果控件中,每一个被实现为一个容器控件。这将允许用户或者直接把文本键入到该容器,或把一个标签放到该控件中并且把相应效果应用到这个标签上。选择使用一个标签控件的目的是为了提供一种容易的基于标准HTML的方法来实现调整大小、居中放置以及格式化文本。
剩下的5个控件用于在一个web页面中添加页面过渡效果而不用编写任何额外的HTML或VB代码。为了使用这些控件,用户仅需要把它们拖动到表单上。然而,这些控件没有相应的可视化组件,尽管页面能够被显示到浏览器中;当用户离开页面时,相应的过渡效果用于打开下一个页面。
相应于本文的示例工程中包含了一个简单的网站,含有单个default.aspx页面;该页面逐个展示上面的6个文本增强控件和一个页面过渡效果控件。
注意 本文中应用于演示工程和控件库的方法仅适用于Internet explorer,并没有针对其它浏览器类型提供支持。如果你在一家企业内网中工作并且你能够确保所有的用户都能够存取Internet explorer,那么这个控件集和这里的方法可能对你很有用。如果你公开地发布这些控件,那么,使用一个非Internet explorer浏览器冲浪的用户仍然能够读取相应的文本但是该效果将不存在。如果你确实想进行公开发布,那么你可以首先检查用户的浏览器并且如果它不是IE的话,你应该建议他们最好使用IE来观看该站点。
图1.在该演示工程中的过滤效果 |
二、开始
首先,解压源码中包括的类库和演示工程。在检查相应的内容时,你将看到在一个方案中有两个工程。工程DxFilterControls是一个类库,它包含前面提到的11个控件。工程DxFilterTestSite是演示网站,这些控件能够显示于其上,并且可以在单个default.aspx web页面中观看。
在DX过滤控件工程中,有11个独立的控件:
1. CCBlurredLabel 2. CCDropShadow 3. CCEmboss 4. CCEngrave 5. CCGlowingText 6. CCGradient 7. CCPageTransition_Iris 8. CCPageTransition_Pixelate 9. CCPageTransition_RadialWipe 10. CCPageTransition_GradientWipe 11. CCPageTransition_Wheel |
我已经提到,前6个控件用于增强文本外观(通过一个微软DirectX过滤应用程序实现)。这些控件中的每一个都被构造为一个容器,并且任何直接放入容器或标签中的文本都会拥有相应的过滤效果,只要它能够被生成到一个微软Internet explorer浏览器。
前5个控件专门用于为容器内容提供一些文本改进过滤。第6个控件(CCGradient)仅是一个面板,它具有一个渐变背景并且它并不实际改变或直接影响在该容器中的文本。
第7到第11个控件是页面过渡效果控件。你可以把单个页面过渡控件拖动到一个表单并且设置它的属性(其中,许多属性不用设置)。结果,当用户退出当前页面时,要打开的下一个页面将被使用指定的效果打开。虽然在这个实例中,我使用这些控件来建立一种过渡效果(当过渡到一个新的页面时),但是,这些过渡效果可以被配置以便当加载容器页面时调用该效果,甚至可以把这些过渡效果使用于单个页面内来实现使用一个新图像代替另一个图像的效果。
图2:像素化页面过渡效果 |
另外,这并不是一组十分复杂的控件,但是我认为它们已经足已能够展示通过DirectX能够取得什么样的过滤效果。你可以参考网站上的有关微软文档来探讨其它过滤效果。
三、文本增强过滤效果控件
包含在示例控件库中的上面6个文本改进效果控件中的每一个基本上都是以相同的格式创建。在此,我们不想逐个描述这些控件,而只描述一下CCEmboss控件。该CCEmboss控件继承自System.Web.UI.WebControl;我已经把对System.Design的引用添加到基本web控件上,并且添加了一个import语句以便在工程中包括System.Web.UI.Design库。这种添加对于建立一些设计时刻支持元素(以便使该控件在设计时刻更易于使用)是必要的。该代码被分为三个独立的区域:Declarations,Properties和Rendering。下面,让我们看一下该类定义的开始:
Imports System Imports System.Collections.Generic Imports System.ComponentModel Imports System.Text Imports System.Web Imports System.Web.UI Imports System.Web.UI.Design Imports System.Web.UI.WebControls <Designer(GetType(EmbossedLabelDesigner))>_ <ParseChildren(False)>_ Public Class CCEmboss Inherits WebControl |
注意,在import语句后,属性数据显示该类将使用一个包含在EmbossedLabelDesigner类中的定制设计器。后面,我们将描述这个设计器,它负责为该控件提供某种设计时刻支持。还要注意,已经添加了ParseChildren属性并且被设置为false。这是为了防止页面分析器分析该控件的内容,因为该控件是一个容器控件并且它的内容不属于那个控件一部分。
Declarations区域跟随其后而且很简单;它包含几个private型成员变量用于存储用户对这个控件的选择信息。有关这个过滤效果,你可以参考一下微软文档来确定是否还有任何其它需要探讨的属性。
#Region "Declarations" Private mEnabled As Boolean Private mBias As Single #End Region |
在此,mEnabled属性是一个布尔值,它将被传递到过滤效果中,并且它恰好能实现你希望的效果;它能够启动或停用该效果。这里的mBias用于决定事件的范围。我相信微软文档在这个问题上显示,0.7是典型的并且是针对这种效果的缺省值。
接下来是Properties区域,它的内容限于对private型成员变量的内容提供公共存取。其实现代码大致如下:
#Region "Properties" <Category("Embossed Label")>_ <Browsable(True)>_ <Description("Enable or display the embossed effect.")>_ Public Property EmbossEnabled() As Boolean Get EnsureChildControls() Return mEnabled End Get Set(ByVal value As Boolean) EnsureChildControls() mEnabled = value End Set End Property <Category("Embossed Label")>_ <Browsable(True)>_ <Description("Set the bias for the embossed effect (typically 0.7).")>_ Public Property Bias() As Single Get EnsureChildControls() Return mBias End Get Set(ByVal value As Single) EnsureChildControls() mBias = value End Set End Property #End Region |
最后一部分是Rendering区域。它包含在运行时刻激活该效果的必要代码;其代码大致如下所示:
#Region "Rendering" Protected Overrides Sub AddAttributesToRender(ByVal writer As HtmlTextWriter) writer.AddStyleAttribute(HtmlTextWriterStyle.Filter, _ "progid:DXImageTransform.Microsoft.Emboss(bias=" & Bias.ToString() & _ ",enabled = " & EmbossEnabled.ToString() & ");width:" & Width.Value.ToString() & "px") MyBase.AddAttributesToRender(writer) End Sub #End Region End Class |
注意,在此我们重载了AddAttributesToRender子例程,并且使用HtmlTextWriter来添加一个style属性。该属性相应于DirectX过滤器。你还能够看到,这个较早暴露的属性被传递给在该过滤器定义内的这个子例程。这是在运行时刻把过滤效果添加到容器的位置。
这一节后面是EmbossedLabelDesigner类的定义。这个类可以被写入一个单独的类文件中;然而我更喜欢这种方法,因为它使设计代码及相应目标一切都那么清晰。这部分代码为该控件提供设计时刻支持:
Public Class EmbossedLabelDesigner Inherits ContainerControlDesigner Protected Overrides Sub AddDesignTimeCssAttributes(ByVal styleAttributes As System.Collections.IDictionary) Dim embossLbl As CCEmboss = CType(Me.Component, CCEmboss) styleAttributes.Add("filter","progid:DXImageTransform.Microsoft.Emboss(bias=" & embossLbl.Bias.ToString() & ",enabled = " & embossLbl.Enabled.ToString() & ");width:" & embossLbl.Width.Value.ToString() & "px") MyBase.AddDesignTimeCssAttributes(styleAttributes) End Sub End Class |
如你所见,你基本上在该控件上添加了与在运行时刻一样的过滤效果,以便你能够看到该过滤的相同的可视化效果;然而,你现在使用的是表单设计器。这一点很好地归纳了这其中每个控件的工作方式,尽管你会注意到在表单的其它属性和方法中也存在一些微小区别。
四、页面过渡效果控件
这一节,象前一节一样,我们将仅讨论5个页面过渡效果控件之一(因为它们之间具有极大的相似性)。我将讨论渐变擦除过渡效果控件;请参考本文提供的示例代码来进一步了解这个控件与其它控件之间的区别。
该渐变擦除页面过渡控件(CCPageTransitition_GradientWipe)以一种与文本改进控件相似的方式开始。实现代码被划分成三个主要的区域:Declarations,Properties和Rendering。
该类声明部分看起来如下所示:
Imports System Imports System.Collections.Generic Imports System.ComponentModel Imports System.Text Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls ''' <summary> ''' 过渡效果(仅适用于Internet Explorer) '''把这个控件拖动到一个页面上;当这个页面被退出时,下一个页面将会通过过渡 '''效果(Gradient Wipe)进行显示 ''' </summary> ''' <remarks></remarks> Public Class CCPageTransitition_GradientWipe Inherits WebControl Private Sub CCPageTransitition_GradientWipe_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init Me.Width = 20 Me.Height = 20 End Sub |
你会注意到,我们没有把System.Web.UI.Design导入到这个类中,因为对于这个控件来说,不存在可能的设计时刻可视化内容。你可能还注意到,该控件的初始化用来把该控件的高度和宽度设置为各自20个像素。这仅在设计时刻在页面的表单(一个空框)上创建一些指示时才需要。这个框在运行时刻不会出现在web表单上。
在类初始化之后,我添加了下面的Declarations区域。这个区域用于存储该类中的每一个private型成员变量。这个区域的声明看起来如下所示:
#Region "Declarations" Private mDuration As Single = 1 #End Region |
你可以看出,该类中只使用了一个私有成员变量。在Declarations区域后面,跟着的是Properties区域;它看上去如下所示:
#Region "Properties" <Category("Gradient Wipe Transition")> _ <Browsable(True)> _ <Description("Set the effect duration (typically 1 or 2)")> _ Public Property TransitionDuration() As Single Get Return mDuration End Get Set(ByVal value As Single) mDuration = value End Set End Property #End Region |
这个属性用于设置发生页面过渡效果的时间长度。下面,我们来看一下生成(redering)区域块的代码:
#Region "Rendering" Protected Overrides Sub RenderContents(ByVal writer As System.Web.UI.HtmlTextWriter) Try Dim sb As New StringBuilder sb.Append("<meta http-equiv='Page-Exit' ") sb.Append("content='progid:DXImageTransform. _ Microsoft.gradientWipe(duration=" & TransitionDuration.ToString() & ")' />") writer.RenderBeginTag(HtmlTextWriterTag.Div) writer.Write(sb.ToString()) writer.RenderEndTag() Catch ex As Exception writer.RenderBeginTag(HtmlTextWriterTag.Div) writer.Write("Gradient Wipe Transition Control") writer.RenderEndTag() End Try End Sub #End Region End Class |
这部分代码相当直接,RenderContents子例程被重载,新的内容被包括到一个try-catch块内。尽管我没有处理任何错误(在出现错误的情况下),我只把字符串"Gradient Wipe Transition Control"写到一个div中,作为一个可放置于此的控件的占位符。
在该try块内的代码仅使用一个字符串构建器来格式化我们想在运行时刻直接放到该web页面的源中的文本。该字符串构造器中包含的代码用于建立请求,从而把页面exit事件与页面过滤效果加以关联。你可能还注意到,duration属性被传递到字符串构造器用于设置过滤器使用的duration参数的值。
在配置该字符串构造器之后,该字符串构造器的内容被写到页面上。无论何时该示例类库中的这个或任何其它页面过渡控件被添加到一个页面,页面退出显示出同样的属性;结果是,无论何时用户离开该页面,下一个页面都将使用该过渡效果显示。
五、 结论
就此结束吧!其实,我还建议你研究一下其它的控件并逐个在测试网站中进行试验。还存在其它一些过滤效果和页面过渡可用,我想你一定希望进一步扩展这个库;同样,还有其它一些有关过滤的属性需要进一步讨论。最后,祝你编程愉快!