自訂控制元件的 Visual Studio 設計時間支援 (Windows Forms .NET)

如同您在與 Windows Form設計工具互動時所注意到的,Windows Form控件提供許多不同的設計時間功能。 Visual Studio Designer 提供的一些功能包括貼齊線、動作專案和屬性方格。 所有這些功能都可讓您更輕鬆地在設計時間互動和自定義控制件。 本文概述您可以新增至自定義控件的支援類型,讓設計時間體驗更適合控件的取用者。

重要

.NET 7 和 .NET 6 的桌面指南檔正在建置中。

與 .NET Framework 不同的內容

許多自定義控件的基本設計元素都與 .NET Framework 一樣。 不過,如果您使用更進階的設計工具自定義功能,例如動作清單、類型轉換器、自定義對話方塊,您有一些獨特的案例可處理。

Visual Studio 是以 .NET Framework 為基礎的應用程式,因此,您為 Windows Form看到的可視化設計工具也是以 .NET Framework 為基礎。 使用 .NET Framework 專案時,Visual Studio 環境和設計所在的 Windows Form應用程式都會在同一個進程中執行, devenv.exe。 當您使用 Windows Form.NET (而非 .NET Framework) 應用程式時,這會造成問題。 .NET 和 .NET Framework 無法在同一個進程中運作。 因此,Windows Form的 .NET 使用不同的設計工具「跨進程」設計工具。

跨進程設計工具是一個稱為 DesignToolsServer.exe 的程序,並且會與 Visual Studio 的 devenv.exe 程式一起執行。 DesignToolsServer.exe進程會在您應用程式的目標相同版本和平台中執行,例如 .NET 7 和 x64。 當您的自定義控件需要在devenv.exe中顯示 UI 時,自定義控件必須實作客戶端伺服器架構,以利devenv.exe通訊。 如需詳細資訊,請參閱設計工具自 .NET Framework 以來的變更(Windows Form.NET)。

屬性視窗

Visual Studio [屬性 ] 視窗會顯示所選控件或表單的屬性和事件。 這通常是您在自定義控件或元件上執行的第一個自定義點。

下圖顯示 Button Visual Designer 中選取的控件,以及顯示按鈕屬性的屬性方格:

Visual Studio 中的 Windows Form設計工具,其中顯示按鈕和屬性視窗

您可以在屬性方格中控制自定義控件相關信息的一些層面。 屬性會套用至自定義控件類別或類別屬性。

類別的屬性

下表顯示您可以套用的屬性,以指定自訂控制項和元件在設計階段的行為。

屬性 描述
DefaultEventAttribute 指定元件的預設事件。
DefaultPropertyAttribute 指定元件的預設屬性。
DesignerAttribute 指定用來實作元件之設計階段服務的類別。
DesignerCategoryAttribute 指定類別的設計工具屬於特定的分類。
ToolboxItemAttribute 代表工具箱項目的屬性。
ToolboxItemFilterAttribute 指定用於工具箱項目的篩選字串和篩選類型。

屬性的屬性

下表描述的屬性 (Attribute) 可套用至自訂控制項和元件的屬性 (Property) 或其他成員。

屬性 描述
AmbientValueAttribute 指定要傳遞至屬性的值,讓屬性從其他來源取得其值。 這稱為「環境」
BrowsableAttribute 指定是否應該在 [屬性] 視窗中顯示屬性或事件。
CategoryAttribute 指定要在控件中 PropertyGrid 設定為 Categorized 模式時,將屬性或事件分組的類別名稱。
DefaultValueAttribute 指定屬性的預設值。
DescriptionAttribute 指定屬性或事件的描述。
DisplayNameAttribute 指定屬性、事件或公用方法的顯示名稱,這個方法不會傳回值,而且不接受任何自變數。
EditorAttribute 指定用來變更屬性的編輯器。
EditorBrowsableAttribute 指定在編輯器中可檢視的屬性或方法。
HelpKeywordAttribute 指定類別或成員的內容關鍵字。
LocalizableAttribute 指定是否應該當地語系化屬性。
PasswordPropertyTextAttribute 表示物件的文字表示是由星號等字元所隱藏。
ReadOnlyAttribute 指定這個屬性 (Attribute) 所繫結的屬性 (Property) 在設計階段是唯讀或讀寫。
RefreshPropertiesAttribute 指出屬性方格應該在關聯的屬性值變更時重新整理。
TypeConverterAttribute 指定要用來做為此屬性所繫結至物件的型別轉換子。

自定義控件設計工具

藉由撰寫相關聯的自定義設計工具,即可增強自定義控件的設計時間體驗。 根據預設,您的自定義控件會顯示在主機的設計介面上,看起來與運行時間相同。 透過自訂設計工具,您可以增強控件的設計時間檢視、新增動作專案、貼齊線和其他專案,以協助用戶判斷如何配置和設定控件。 例如,在設計時間, ToolStrip 設計工具會新增額外的控件,讓使用者新增、移除及設定個別專案,如下圖所示:

Visual Studio 中的 Windows Form設計工具,顯示分割容器的設計時間檢視。

您可以執行下列步驟來建立自己的自訂設計工具:

  1. 新增 Microsoft.WinForms.Designer.SDK NuGet 套件參考。
  2. 建立類型繼承自 Microsoft.DotNet.DesignTools.Designers.ControlDesigner 類別。
  3. 在使用者控件類別中,將 類別標示為 System.ComponentModel.DesignerAttribute 類別屬性,並傳遞您在上一個步驟中建立的類型。

如需詳細資訊,請參閱 與 .NET Framework 不同的部分。

動作項目

設計工具動作是內容敏感的功能表,可讓使用者快速執行一般工作。 例如,如果您將 新增 TabControl 至表單,您要在控制項中新增和移除索引標籤。 索引標籤是在 [屬性] 視窗中管理,透過TabPages屬性來顯示索引標籤集合編輯器。 不會強制使用者一律篩選 [屬性 ] 列表尋找 TabPages 屬性,而是 TabControl 提供智慧標記按鈕,只有在選取控件時才會顯示,如下圖所示:

Visual Studio 中的 Windows Form設計工具,顯示選項卡控件的智慧標記按鈕。

選取智慧標記時,會顯示動作清單:

Visual Studio 中的 Windows Form設計工具顯示按下 Tab 控件的智慧標記按鈕,其中顯示動作清單。

藉由新增 [ 新增索引標籤 ] 和 [移除索引 卷標] 動作,控件的設計工具會讓它快速新增或移除索引卷標。

建立動作項目清單

動作項目清單是由 ControlDesigner 您所建立的類型所提供。 下列步驟是建立您自己的動作清單的基本指南:

  1. 新增 Microsoft.WinForms.Designer.SDK NuGet 套件參考。
  2. 建立繼承自 Microsoft.DotNet.DesignTools.Designers.Actions.DesignerActionList的新動作清單類別。
  3. 將屬性新增至您想要使用者存取的動作清單。 例如,將 或 Boolean (在 Visual Basic 中) 屬性新增bool至 類別會在動作清單中建立CheckBox控制件。
  4. 請遵循 [自定義控件設計工具] 區段中的步驟來建立新的設計工具。
  5. 在設計工具類別中,覆寫 ActionLists 會傳回 Microsoft.DotNet.DesignTools.Designers.Actions.DesignerActionListCollection 類型的屬性。
  6. 將動作清單新增至 DesignerActionListCollection 實例,並傳回它。

如需動作清單的範例,請參閱 Windows Form設計工具擴充性檔和範例 GitHub 存放庫,特別是 TileRepeater.Designer.Server/ControlDesigner 資料夾。

在 [ 屬性 ] 視窗中,大部分的屬性很容易在方格中編輯,例如當屬性的支援類型是列舉、布爾值或數位時。

適用於 Windows Form應用程式的 Visual Studio 屬性視窗,其中顯示對齊屬性。

有時候,屬性會比較複雜,而且需要用戶可用來變更屬性的自定義對話框。 例如,屬性 FontSystem.Drawing.Font 類型,其中包含許多改變字型外觀的屬性。 這不容易顯示在 [ 屬性 ] 視窗中,因此此屬性會使用自定義對話框來編輯字型:

Windows Form應用程式的 Visual Studio 字型對話方塊。

如果您的自定義控件屬性使用 Windows Form提供的內建類型編輯器,您可以使用 EditorAttribute 來標記屬性與您想要 Visual Studio 使用的對應 .NET Framework 編輯器。 藉由使用內建編輯器,您可以避免復寫跨進程設計工具所提供的 Proxy-object client-server 通訊。

參考內建類型編輯器時,請使用 .NET Framework 類型,而不是 .NET 類型:

[Editor("System.Windows.Forms.Design.FileNameEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
        "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public string? Filename { get; set; }
<Editor("System.Windows.Forms.Design.FileNameEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")>
Public Property Filename As String