6 wpf user-controls install toolbox visual-studio
我正在尝试为WPF控件创建一个VSIX安装程序.
它应该很简单,但"简单"版本假定您在VSIX项目中创建WPF控件.
问题是,我的UserControl深藏在我的一个DLL中,我不相信把它拉出来是最好的设计.我想把它留在那里,但我似乎无法做到这一点并将控件添加到工具箱中.
一种选择是将我需要的代码移动到工具箱中的控件程序集中,但这会向Microsoft.VisualStudio.Shell.Immutable.10.0.dll添加依赖项.安装了Visual Studio的人和在未安装VS的服务中运行的远程服务器都使用该程序集,因此这是不行的.
我尝试的另一个选项是通过将RegistrationAttribute应用于代理来"欺骗"工具箱安装程序VSIX,代理将注册在另一个程序集中定义的类型.认为它会起作用,但奇怪的事情发生了.

我没有得到两个控件,而是在奇怪命名的选项卡中获得了一堆Border控件(标准的WPF边框),其中一些控件回显了我的一些命名空间.
当在VSIX以外的程序集中定义控件时,如何使用工具箱注册WPF UserControl?
我能够提出类似于您提到的代理想法的概念证明。
您看到的问题是由错误的程序集注册引起的,因此我创建了一个名为 的新注册属性,ProvideProxyToolboxControlAttribute该属性用作 VS 集成程序集中的代理类的属性。它几乎与 相同,ProvideToolboxControlAttribute只是它采用实际控件的类型。当然,这个新属性也将位于您的 VS 程序集中。
例如,假设我的非 VS 程序集中有一个名为 的工具箱控件MyToolboxControl,我会在 VS 程序集中创建一个简单的代理类MyToolboxControlProxy,如下所示:
[ProvideProxyToolboxControl("MyToolboxControl", typeof(NonVsAssembly.MyToolboxControl))]
public class ToolboxControlProxy
{
}
Run Code Online (Sandbox Code Playgroud)
当然,神奇的事情发生在 中ProvideProxyToolboxControlAttribute,它基本上就是这个类(为简洁起见,删除了注释和参数/错误检查):
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
[System.Runtime.InteropServices.ComVisibleAttribute(false)]
public sealed class ProvideProxyToolboxControlAttribute : RegistrationAttribute
{
private const string ToolboxControlsInstallerPath = "ToolboxControlsInstaller";
public ProvideProxyToolboxControlAttribute(string name, Type controlType)
{
this.Name = name;
this.ControlType = controlType;
}
private string Name { get; set; }
private Type ControlType { get; set; }
public override void Register(RegistrationAttribute.RegistrationContext context)
{
using (Key key = context.CreateKey(String.Format(CultureInfo.InvariantCulture, "{0}\\{1}",
ToolboxControlsInstallerPath,
ControlType.AssemblyQualifiedName)))
{
key.SetValue(String.Empty, this.Name);
key.SetValue("Codebase", ControlType.Assembly.Location);
key.SetValue("WPFControls", "1");
}
}
public override void Unregister(RegistrationAttribute.RegistrationContext context)
{
if (context != null)
{
context.RemoveKey(String.Format(CultureInfo.InvariantCulture, "{0}\\{1}",
ToolboxControlsInstallerPath,
ControlType.AssemblyQualifiedName));
}
}
}
Run Code Online (Sandbox Code Playgroud)
它似乎工作得很好,我验证了该控件位于工具箱中并且添加了正确的注册表项。
希望这可以帮助!