往 VisualStudio 工具箱中添加 WPF/WinForms 控件的几种方式

在使用 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
posted @ 2024-04-07 19:56  theyangfan  阅读(1412)  评论(0编辑  收藏  举报