一、簡介
本文描述一種創建定制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參數的值。
在配置該字符串構造器之后,該字符串構造器的內容被寫到頁面上。無論何時該示例類庫中的這個或任何其它頁面過渡控件被添加到一個頁面,頁面退出顯示出同樣的屬性;結果是,無論何時用戶離開該頁面,下一個頁面都將使用該過渡效果顯示。
五、 結論
就此結束吧!其實,我還建議你研究一下其它的控件并逐個在測試網站中進行試驗。還存在其它一些過濾效果和頁面過渡可用,我想你一定希望進一步擴展這個庫;同樣,還有其它一些有關過濾的屬性需要進一步討論。最后,祝你編程愉快!


