往 VisualStudio 工具箱中新增 WPF/WinForms 控制元件的幾種方式

theyangfan發表於2024-04-07

在使用 VisualStudio 開發 WPF或WinForms應用時,開啟UI檔案的設計介面,我們可以從工具箱的控制元件列表中直接拖拽控制元件到介面上。透過這種方式,可以清晰的展示控制元件庫中所有可用的控制元件,並且非常方便的將其新增到介面中。那麼我們可以透過哪些方式將WPF/WinForms控制元件庫中的控制元件新增到VisualStudio的工具箱呢?本文就對此做一個簡單的總結。

我們知道,.NET Core 3.0 及以上版本提供了對 WPF/WinForm 框架的支援,而VS工具箱對其 .NET Framework 和 .NET(Core) 控制元件的支援存在一定的差異,所以接下來以 WPF 控制元件庫為例,分別建立名為 MyWpfControlsForFramework 和 MyWpfControlsForCore 的 WPF 使用者控制元件庫,其目標框架分別為 .NET Framework 4.8 和 .NET 6,其中都包含一個名為 Control1 的控制元件,編譯後分別得到對應的DLL檔案。

1. WPF .NET Framework 控制元件

.NET Framework 的控制元件可以透過以下幾個方式新增到VS工具箱中:

1.1 手動新增

新建 WPF .NET Framework 4.8 應用專案,雙擊開啟 MainWindow.xaml 檔案,進入設計介面,展開工具箱視窗,右鍵新增選項卡 MyWpfControls,然後將之前生成的 MyWpfControlsForFramework.dll 拖到該選項卡下,即可完成新增,如下圖:

1.2 透過 NuGet 安裝

這種方式需要我們將庫專案打包成 NuGet 包,並在包中新增 tools/VisualStudioToolsManifest.xml 檔案,檔案內容如下:

<FileList>
    <File Reference = "MyWpfControlsForFramework.dll">
        <ToolboxItems UIFramework="WPF" VSCategory="MyWpfControls">
            <Item Type="MyWpfControlsForFramework.Control1" />
        </ToolboxItems>
    </File>
</FileList>

其中,Reference 是程式集名稱,VsCategory 是選項卡名稱,其中的Item 表示要新增到工具箱中的控制元件的完全限定名稱。
這樣,透過NuGet包管理器安裝此包時就會將控制元件新增到VS工具箱。該方式支援 VS 2017 15.0 及以上版本。

1.3 Visual Studio Toolbox Controls Installer (TCI)

TCI 是 VS 的一項用於向工具箱安裝控制元件的功能,它透過搜尋登錄檔項的方式來查詢控制元件。有3種方式可以利用此功能,下面介紹其中一種設定 AssemblyFoldersEx 登錄檔項的方式:

  1. 將程式集儲存到某一自定義目錄下,如:C:\MyWpfAssemblies;
  2. 開啟登錄檔編輯器,找到 HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx 項;
  3. AssemblyFoldersEx項下新建子項,名稱自定義,例如MyWpfControls,修改預設值為程式集所在目錄 C:\MyWpfAssemblies
  4. MyWpfControls項下新建Toolbox子項,在該子項中新增名為TabName字串值,值為要在VS工具箱中顯示的選項卡名稱,例如MyWpfControls

這樣,工具箱在載入時,就會檢查登錄檔,並將控制元件新增到其中。
另外,如果我們更新了程式集,例如新增了控制元件,那麼就必須更新登錄檔項。因為只有這樣,TCI才會更新工具箱中的控制元件。因此,我們可以在 Toolbox 項中新增一個名為 Version 的 DWORD值,值的資料沒有要求,只是為了觸發這一機制。那麼在更新程式集後,也同時更新 Version 的值,就可以及時的更新工具箱中的控制元件。最終結果如下所示:


透過這種方式不需要新增對程式集的引用,即可在VS工具箱中顯示控制元件,支援 VS 2010 及以上版本。另外,新增程式集和登錄檔的步驟可以透過“安裝程式”來完成。

2. WPF .NET 6 控制元件

.NET 6 的控制元件可以透過以下幾個方式新增到VS工具箱中:

2.1 透過 NuGet 安裝

該方式與 .NET Framework 一樣,需要我們將庫專案打包成 NuGet 包,並在包中新增 tools/VisualStudioToolsManifest.xml 檔案,檔案內容與Framework一致。當然,為了打包方便,我們可以將該檔案放到專案目錄下,然後在專案檔案中新增如下配置:

<PropertyGroup>
  <TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);VSToolsManifest</TargetsForTfmSpecificContentInPackage>
</PropertyGroup>

<Target Name="VSToolsManifest">
  <ItemGroup>
    <TfmSpecificPackageFile Include="tools\VisualStudioToolsManifest.xml">
      <PackagePath>tools</PackagePath>
    </TfmSpecificPackageFile>
  </ItemGroup>
</Target>

其中IncludeVisualStudioToolsManifest.xml 檔案相對專案檔案的路徑,PackagePath 是該檔案最終在 NuGet 包中的目錄路徑。該方式支援 VS 2017 15.0 及以上版本。

2.2 將 NuGet 包新增到 NuGet Fallback 目錄

使用這種方式,我們不需要在專案中新增對包的引用,即可在VS工具箱中顯示其控制元件。

  1. 開啟 C:\Program Files (x86)\NuGet\Config 目錄,新建 MyFallback.config 檔案,檔案內容如下:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <fallbackPackageFolders>
    <add key="My NuGet Fallback Folder" value="C:\MyNuGetFallbackFolder" />
  </fallbackPackageFolders>
</configuration>

其中,key 的值應避免和同目錄下其他檔案內的一致,value 是自定義的 Fallback 目錄。

  1. 下載 nuget.exe

  2. 執行以下指令將上一種方式生成的 NuGet 包擴充套件到 fallback 目錄:

nuget.exe add MyWpfControlsForCore.nupkg -Source C:\MyNuGetFallbackFolder -Expand

最終,在 C:\MyNuGetFallbackFolder 中會新增一個MyWpfControlsForCore目錄。使用 nuget.exe 而不是簡單的解壓nupkg檔案的原因是 nuget.exe 會生成一個 .nuget.metadata 檔案,當 NuGet 恢復時需要此檔案。
當使用安裝程式安裝此包時,建議將此擴充套件好的資料夾新增到安裝程式中,由安裝程式將其複製到使用者機上,而不是在使用者機上呼叫 nuget.exe。這種方式支援 VS 2019 16.7 Preview 2 及以上版本。

以上就是往 VisualStudio 工具箱中新增 WPF/WinForms 控制元件的幾種方式,除此之外還有其他的幾種方式,詳情可以看參考連結。

參考

  1. https://github.com/microsoft/xaml-designer-extensibility/blob/main/documents/toolbox-population.md#toolbox-items-from-unreferenced-assemblies
  2. https://learn.microsoft.com/zh-cn/visualstudio/extensibility/creating-a-wpf-toolbox-control?view=vs-2022

相關文章