有一些控制項在執行階段是不會呈現,也就是說控制項本身在執行階段不會 Render 出 HTML 碼,例如 SqlDataSoruce、ScriptManager 這類控制項;那它們在設計階段的頁面是如何呈現出來呢?本文將針對控制項設計階段的外觀做進一步的說明。
程式碼下載:ASP.NET Server Control - Day19.rar
一、控制項設計階段的 HTML 碼
Web 伺服器控制項的設計模式行為都是透過 ControlDesigner 來處理,連設計階段時控制項的外觀也是如此;控制項在設計階段與執行執行時呈現的外觀不一定相同,當然大部分會儘量一致,使其能所見即所得。
控制項在設計階段的 HTML 碼是透 ControlDesigner.GetDesignTimeHtml 方法來處理,在 ControlDesigner.GetDesignTimeHtml 預設會執行控制項的 RenderControl 方法,所以大部分的情況下設計階段與執行階段輸出的 HTML 碼會相同。當控制項的 Visible=False 時,執行階段是完全不會輸出 HTML 碼,可是在設計階段時會特別將控制項設定 Visible=True,使控制項能完整呈現。
ControlDesigner.GetDesignTimeHtml 方法
Public Overridable Function GetDesignTimeHtml() As String
Dim writer As New StringWriter(CultureInfo.InvariantCulture)
Dim writer2 As New DesignTimeHtmlTextWriter(writer)
Dim errorDesignTimeHtml As String = Nothing
Dim flag As Boolean = False
Dim visible As Boolean = True
Dim viewControl As Control = Nothing
Try
viewControl = Me.ViewControl
visible = viewControl.Visible
If Not visible Then
viewControl.Visible = True
flag = Not Me.UsePreviewControl
End If
viewControl.RenderControl(writer2)
errorDesignTimeHtml = writer.ToString
Catch exception As Exception
errorDesignTimeHtml = Me.GetErrorDesignTimeHtml(exception)
Finally
If flag Then
viewControl.Visible = visible
End If
End Try
If ((Not errorDesignTimeHtml Is Nothing) AndAlso (errorDesignTimeHtml.Length <> 0)) Then
Return errorDesignTimeHtml
End If
Return Me.GetEmptyDesignTimeHtml
End Function
二、自訂控制項的 Designer
以 TBToolbar 為例,若我們在 RenderContents 方法未針對 Items.Count=0 做輸出 HTML 的處理,會發現未設定 Items 屬性時,在設計頁面上完全看不到 TBToolbar 控制項;像這種控制項設計階段的 HTML 碼,就可以自訂控制項的 Designer 來處理。
繼承 ControlDesigner 命名為 TBToolbarDesigner,這個類別是用來擴充 TBToolbar 控制項的設計模式行為。我們可以覆寫 GetDesignTimeHtml 方法,處理設計階段表示控制項的 HTML 標記,此方法回傳的 HTML 原始碼就是控制項呈現在設計頁面的外觀。所以我們可以在 TBToolbar.Items.Count=0 時,輸出一段提示的 HTML 碼,這樣當 TBToolbar 未設定 Items 屬性時一樣可以在設計頁面上呈現控制項。
''' <summary>
''' 擴充 TBToolbar 控制項的設計模式行為。
''' </summary>
Public Class TBToolbarDesigner
Inherits System.Web.UI.Design.ControlDesigner
''' <summary>
''' 用來在設計階段表示控制項的 HTML 標記。
''' </summary>
Public Overrides Function GetDesignTimeHtml() As String
Dim sHTML As String
Dim oControl As TBToolbar
oControl = CType(ViewControl, TBToolbar)
If oControl.Items.Count = 0 Then
sHTML = "<div style=""background-color: #C0C0C0; border:solid 1px; width:200px"">請設定 Items 屬性</div>"
Else
sHTML = MyBase.GetDesignTimeHtml()
End If
Return sHTML
End Function
End Class
在 TBToolbar 控制項套用 DesignerAttribute 設定自訂的 TBToolbarDesigner 類別。
<Designer(GetType(TBToolbarDesigner))> _
Public Class TBToolbar
Inherits WebControl
End Class
重建控制項組件,切換到設計頁面上的看 TBToolbar 控制項未設定 Items 屬性時的外觀,就是我們在 TBToolbarDesigner.GetDesignTimeHtml 方法回傳的 HTML 碼。
如果你覺得上述設計階段的控制項有點太陽春,我們也可以輸出類似 SqlDataSource 控制項的外觀,將未設定 Items 屬性時輸出 HTML 改呼叫 CreatePlaceHolderDesignTimeHtml 方法。
If oControl.Items.Count = 0 Then
sHTML = MyBase.CreatePlaceHolderDesignTimeHtml("請設定 Items 屬性")
Else
sHTML = MyBase.GetDesignTimeHtml()
End If
來看一下這樣修改後的結果,是不是比較專業一點了呢。
備註:本文同步發佈於筆者「ASP.NET 魔法學院」部落格
http://www.dotblogs.com.tw/jeff377/archive/2008/10/20/5726.aspx