本文說明如何在 Visual Studio 的 Windows Forms 視覺化設計工具中處理控制項的屬性。
每個控制項都會從基底類別 System.Windows.Forms.Control 繼承許多屬性,例如:
建立控制項時,您可以定義新的屬性,並控制它們在設計工具中的顯示方式。
定義屬性
任何具有控制項所定義 get 存取子的公用屬性,都會在 Visual Studio 的 [屬性] 視窗中自動顯示。 如果屬性也定義了 set 存取子,則可以在 [屬性] 視窗中變更該屬性。 不過,可以藉由套用 ,在 [屬性]BrowsableAttribute 視窗中明確顯示或隱藏屬性。 這個屬性採用單一布林值參數來指出是否顯示。 如需有關屬性的詳細資訊,請參閱屬性 (C#) 或屬性概觀 (Visual Basic)。
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsSelected { get; set; }
<Browsable(False)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Property IsSelected As Boolean
備註
無法直接轉換為字串的複雜屬性需要型別轉換器。
序列化屬性
控制項設定的屬性會經過序列化後寫入設計工具的程式碼後置檔案。 當屬性的值設定為預設值以外的值時,即會發生此狀況。
當設計工具偵測到屬性的變更時,即會評估該控制項的所有屬性,並將值不符合該屬性預設值的任何屬性進行序列化。 屬性的值會序列化成為設計工具的程式碼後置檔案。 預設值可協助設計工具判斷應序列化哪些屬性值。
預設值
當屬性套用 DefaultValueAttribute 屬性,或屬性的類別包含屬性特定的 Reset
和 ShouldSerialize
方法時,該屬性會被視為具有預設值。 如需有關屬性的詳細資訊,請參閱屬性 (C#) 或屬性概觀 (Visual Basic)。
藉由設定預設值,您可以啟用下列功能:
- 如果屬性已修改過預設值,則會在 [屬性] 視窗中提供視覺指示。
- 使用者可以在屬性上按右鍵,然後選擇 [重設],將屬性還原為其預設值。
- 設計工具會產生更有效率的程式碼。
如果屬性使用簡單類型 (例如基本類型),則可以將 DefaultValueAttribute
套用至屬性來設定預設值。 不過,具有此屬性 (attribute) 的屬性 (properties) 不會自動以該指派的值開頭。 您必須將屬性的支援欄位設定為相同的預設值。 您可以在宣告或類別的建構函式中設定 屬性。
當屬性是複雜類型,或您想要控制設計工具的重設和序列化行為時,請在類別中定義 Reset<PropertyName>
和 ShouldSerialize<PropertyName>
方法。 例如,如果控制項定義 Age
屬性,則方法會命名為 ResetAge
和 ShouldSerializeAge
。
這很重要
將 DefaultValueAttribute
套用至屬性,或提供 Reset<PropertyName>
和 ShouldSerialize<PropertyName>
方法。 請勿混合定義預設值的兩種方式。
若要將屬性「重設」為預設值,請使用 [屬性] 視窗,用滑鼠右鍵按一下屬性名稱,然後選取 [重設]。
在下列情況下,即會啟用 [屬性]>[按右鍵]>[重設] 捷徑功能表選項的可用性:
- 屬性 (property) 已套用 DefaultValueAttribute 屬性 (attribute),而屬性 (property) 的值不符合屬性 (attribute) 的值。
- 屬性的類別定義的
Reset<PropertyName>
方法不含ShouldSerialize<PropertyName>
。 - 屬性的類別定義
Reset<PropertyName>
方法,且ShouldSerialize<PropertyName>
傳回 true。
預設值屬性
如果屬性值不符合 DefaultValueAttribute 提供的值,則該屬性會視為已變更,且可以透過 [屬性] 視窗重設。
這很重要
此屬性不應用於有對應 Reset<PropertyName>
和 ShouldSerialize<PropertyName>
方法的屬性上。
下列程式碼宣告兩個屬性、一個含有預設值 North
的列舉,以及預設值為 10 的整數。
[DefaultValue(typeof(Directions), "North")]
public Directions PointerDirection { get; set; } = Directions.North;
[DefaultValue(10)]
public int DistanceInFeet { get; set; } = 10;
<DefaultValue(GetType(Directions), "North")>
Public Property PointerDirection As Directions = Directions.North
<DefaultValue(10)>
Public Property DistanceInFeet As Integer = 10
Reset 和 ShouldSerialize
如前所述,Reset<PropertyName>
和 ShouldSerialize<PropertyName>
方法不僅有機會引導屬性的重設行為,還能讓您判斷值是否已變更,以及是否應序列化為設計工具的程式碼後置檔案。 這兩種方法必須一起運作,您不得定義其中一個而不定義另一個。
這很重要
若屬性含有 Reset<PropertyName>
,則不得建立 ShouldSerialize<PropertyName>
和 DefaultValueAttribute 方法。
定義 Reset<PropertyName>
時,[屬性] 視窗會顯示該屬性的 [重設] 捷徑功能表選項。 選取 [重設] 時,即會叫用 Reset<PropertyName>
方法。 [重設] 捷徑功能表選項是否啟用,須視 ShouldSerialize<PropertyName>
方法的傳回值而定。 當 ShouldSerialize<PropertyName>
傳回 true
時,表示屬性已變更預設值且應序列化為程式碼後置檔案,並啟用 [重設] 捷徑功能表選項。 傳回 false
時,即會停用 [重設] 捷徑功能表選項,且程式碼後置會移除 property-set 程式碼。
小提示
這兩種方法可以也應該使用私用範圍來定義,這樣才不會構成控制項的公用 API。
下列程式碼片段會宣告名為 Direction
的屬性。 此屬性的設計工具行為是由 ResetDirection
和 ShouldSerializeDirection
方法所控制。
public Directions Direction { get; set; } = Directions.None;
private void ResetDirection() =>
Direction = Directions.None;
private bool ShouldSerializeDirection() =>
Direction != Directions.None;
Public Property Direction As Directions = Directions.None
Private Sub ResetDirection()
Direction = Directions.None
End Sub
Private Function ShouldSerializeDirection() As Boolean
Return Direction <> Directions.None
End Function
類型轉換器
雖然類型轉換器通常會將某個類型轉換成另一個類型,但也可以為屬性方格和其他設計階段控制項提供字串到值的轉換。 字串到值轉換可以在這些設計階段控制項中呈現複雜屬性。
大部分的內建資料類型 (數字、列舉和其他) 都有預設類型轉換器,可提供字串到值的轉換並執行驗證檢查。 預設的類型轉換器位於 System.ComponentModel
命名空間中,並以要轉換的類型命名。 轉換器類型名稱使用下列格式:{type name}Converter
。 例如 StringConverter、TimeSpanConverter 和 Int32Converter。
設計階段的 [屬性] 視窗會大量使用類型轉換器。 類型轉換器可以使用 TypeConverterAttribute 套用至屬性或類型。
當屬性中宣告 時,[屬性]TypeConverterAttribute
視窗會使用轉換器將該屬性顯示為字串值。 在類型中宣告 TypeConverterAttribute
時,[屬性] 視窗會對該類型的每個屬性使用轉換器。 類型轉換器也有助於序列化設計工具程式碼後置檔案中的屬性值。
類型編輯器
當屬性的類型為內建或已知類型時,[屬性] 視窗會自動對屬性使用類型編輯器。 例如,布林值會編輯成含有 True 和 False 值的下拉式方塊,而 DateTime 類型會使用行事曆下拉式清單。
這很重要
自 .NET Framework 之後,自訂類型編輯器已變更。 如需詳細資訊,請參閱設計工具自 .NET Framework 以來的變更。