上篇我們實作了「集合屬性包含不同型別的成員」,不過若有去使用屬性視窗編輯 TBToolbar 的 Items 屬性,你會發覺這個集合屬性編輯器無法加入我們定義不同型別的成員,只能加入最原始的集合成員。是不是只能在 aspx 程式碼中手動去輸入呢?當然不需要這樣人工作業,只要改掉集合屬性編輯器就可以達到我們的需求,本文將介紹修改集合屬性編輯器的相關作法。
程式碼下載:ASP.NET Server Control - Day18.rar
一、自訂集合屬性編輯器
我們先看一下 TBToolbar.Items 屬性套用的 EditorAttribute,它是使用 CollectionEditor 類別來當作屬性編輯器,所以我們就是要繼承 CollectionEditor 類別下來修改成自訂的屬性編輯器。
< _
Editor(GetType(CollectionEditor), GetType(UITypeEditor)) _
> _
Public ReadOnly Property Items() As TBToolbarItemCollection
新增一個繼承 CollectionEditor 的 TBToolbarItemCollectionEditor 類別,並加入建構函式。此類別屬於 Bee.WebControls.Design 命名空間,通常我們會把設計階段使用的類別歸類到特別的命名空間便於管理及使用。
Namespace WebControls.Design
Public Class TBToolbarItemCollectionEditor
Inherits CollectionEditor
''' <summary>
''' 建構函式。
''' </summary>
''' <param name="Type">型別。</param>
Public Sub New(ByVal Type As Type)
MyBase.New(Type)
End Sub
End Class
End Namespace
我們可以先修改 Items 屬性的 EditorAttribute,看看我們自訂的 TBToolbarItemCollectionEditor 是否能正常運作。不過這個屬性編輯器跟原本的沒什麼差異,因為我們只是單純繼承下來沒做任何異動,接下去我們就要開始來修改這個屬性編輯器。
< _
Editor(GetType(TBToolbarItemCollectionEditor), GetType(UITypeEditor)) _
> _
Public ReadOnly Property Items() As TBToolbarItemCollection
二、加入不同型別的集合成員
再來我們就要著手修改集合屬性編輯器,讓它可以加入不同型別的集合成員。覆寫 CollectionEditor 的 CanSelectMultipleInstances 方法傳回 True,這個方法是設定 CollectionEditor 是否允許加入多種不同型別的集合成員。
Protected Overrides Function CanSelectMultipleInstances() As Boolean
Return True
End Function
再來覆寫 CreateNewItemTypes 方法,這個方法是取得這個集合編輯器可包含的資料型別,將集合可包含的資料型別以陣列傳回。
''' <summary>
''' 取得這個集合編輯器可包含的資料型別。
''' </summary>
''' <returns>這個集合可包含的資料型別陣列。</returns>
Protected Overrides Function CreateNewItemTypes() As System.Type()
Dim ItemTypes(2) As System.Type
ItemTypes(0) = GetType(TBToolbarButton)
ItemTypes(1) = GetType(TBToolbarTextbox)
ItemTypes(2) = GetType(TBToolbarLabel)
Return ItemTypes
End Function
重建控制項組件,使用 Items 的集合屬性編輯器,就可以發現「加入」鈕的下拉清單就會出現我們所定義的三種型別的集合成員,如此可以加入不同型別的成員了。
三、設定清單項目的顯示文字
在成員清單項目中預設會顯示成員含命名空間的型別,若我們要修改成比較有識別的顯示文字,例如 TBToolbarButton(Key=Add) 可以顯示「按鈕-Add」,這時可以覆寫 GetDisplayText 方法來設定清單項目的顯示文字。
''' <summary>
''' 取出指定清單項目的顯示文字。
''' </summary>
Protected Overrides Function GetDisplayText(ByVal value As Object) As String
If TypeOf value Is TBToolbarButton Then
Return String.Format("按鈕 - {0}", CType(value, TBToolbarButton).Key)
ElseIf TypeOf value Is TBToolbarTextbox Then
Return "文字框"
ElseIf TypeOf value Is TBToolbarLabel Then
Return String.Format("標籤 - {0}", CType(value, TBToolbarLabel).Text)
Else
Return value.GetType.Name
End If
End Function
四、集合編輯器的屬性視窗的屬性描述
一般屬性視窗下面都會有屬性描述,可以集合屬性編輯器中的屬性視窗下面竟沒有屬性描述。若我們要讓它的屬性描述可以顯示,可以覆寫 CreateCollectionForm 方法,取得集合屬性編輯表單,再去設定表單上的 PropertyGrid.HelpVisible
= True 即可。
備註:本文同步發佈於筆者「ASP.NET 魔法學院」部落格
http://www.dotblogs.com.tw/jeff377/archive/2008/10/19/5721.aspx