在使用 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
登錄檔項的方式:
- 將程式集儲存到某一自定義目錄下,如:
C:\MyWpfAssemblies
; - 開啟登錄檔編輯器,找到
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx
項; - 在
AssemblyFoldersEx
項下新建子項,名稱自定義,例如MyWpfControls
,修改預設值為程式集所在目錄C:\MyWpfAssemblies
; - 在
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>
其中Include
是 VisualStudioToolsManifest.xml
檔案相對專案檔案的路徑,PackagePath
是該檔案最終在 NuGet 包中的目錄路徑。該方式支援 VS 2017 15.0 及以上版本。
2.2 將 NuGet 包新增到 NuGet Fallback 目錄
使用這種方式,我們不需要在專案中新增對包的引用,即可在VS工具箱中顯示其控制元件。
- 開啟
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 目錄。
-
下載 nuget.exe;
-
執行以下指令將上一種方式生成的 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 控制元件的幾種方式,除此之外還有其他的幾種方式,詳情可以看參考連結。
參考
- https://github.com/microsoft/xaml-designer-extensibility/blob/main/documents/toolbox-population.md#toolbox-items-from-unreferenced-assemblies
- https://learn.microsoft.com/zh-cn/visualstudio/extensibility/creating-a-wpf-toolbox-control?view=vs-2022