6

我正在尝试为 WPF 控件创建 VSIX 安装程序。

据说很简单,但“简单”版本假定您在VSIX 项目中创建 WPF 控件。

问题是,我的 UserControl 深藏在我的一个 DLL 中,我不认为将其拉出是最好的设计。我想把它留在那里,但我似乎不能这样做并且将控件添加到工具箱中。

一种选择是将我需要将其安装到工具箱的代码移动到控件的程序集中,但这会向Microsoft.VisualStudio.Shell.Immutable.10.0.dll添加依赖项。该程序集既由安装了 Visual Studio 的人使用,也由在未安装 VS 的服务中运行的远程服务器使用,因此这是不行的。

我尝试的另一个选项是通过将 RegistrationAttribute 应用于将注册其他程序集中定义的类型的代理来“欺骗”工具箱安装程序 VSIX。本以为会成功,但奇怪的事情发生了。

工具箱里的各种奇葩

我没有得到两个控件,而是在奇怪命名的选项卡中得到了一堆边框控件(标准 WPF 边框),其中一些与我的一些命名空间相呼应。

当控件在 VSIX 以外的程序集中定义时,如何使用工具箱注册 WPF 用户控件?

4

1 回答 1

2

我能够提出类似于您提到的代理想法的概念证明。

您看到的问题是由错误程序集的注册引起的,因此我创建了一个名为的新注册属性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));
        }
    }
}

它似乎运行良好,我验证了控件在工具箱中,并且添加了正确的注册表项。

希望这可以帮助!

于 2011-06-25T18:21:39.840 回答