我正在尝试为 WPF 控件创建 VSIX 安装程序。
据说很简单,但“简单”版本假设您在 VSIX 项目中创建 WPF 控件。
问题是,我的 UserControl 深藏在我的一个 DLL 中,我不认为将其拉出来是最好的设计。我想把它留在那里,但我似乎无法做到这一点并将控件添加到工具箱中。
一种选择是将安装到工具箱所需的代码移动到控件的程序集中,但这会添加对 Microsoft.VisualStudio.Shell.Immutable.10.0.dll 的依赖项。该程序集既由安装了 Visual Studio 的人员使用,又由在未安装 VS 的服务中运行的远程服务器使用,因此这是不行的。
我尝试的另一个选项是通过将 RegistrationAttribute 应用到代理来“欺骗”工具箱安装程序 VSIX,代理将注册其他程序集中定义的类型。以为这会起作用,但奇怪的事情发生了。
我没有得到两个控件,而是在命名奇怪的选项卡中得到了一堆 Border 控件(标准 WPF 边框),其中一些与我的一些命名空间相呼应。
当 WPF UserControl 是在 VSIX 之外的程序集中定义时,如何向工具箱注册该控件?
最佳答案
我能够提出类似于您提到的代理想法的概念证明。
您看到的问题是由错误的程序集注册引起的,因此我创建了一个名为 ProvideProxyToolboxControlAttribute
的新注册属性,该属性用作您所拥有的代理类的属性你的 VS 集成组件。它与 ProvideToolboxControlAttribute
几乎相同,只是它采用实际控件的类型。当然,这个新属性也将位于您的 VS 程序集中。
例如,假设我的非 VS 程序集中有一个名为 MyToolboxControl
的工具箱控件,我会在 VS 程序集中创建一个简单的代理类 MyToolboxControlProxy
,它看起来如下像这样:
[ProvideProxyToolboxControl("MyToolboxControl", typeof(NonVsAssembly.MyToolboxControl))]
public class ToolboxControlProxy
{
}
当然,神奇的事情发生在 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));
}
}
}
它似乎工作得很好,我验证了该控件位于工具箱中并且添加了正确的注册表项。
希望这有帮助!
关于用于在不同程序集中定义的类型的 WPF 工具箱安装程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5008791/