65.9K
CodeProject 正在变化。 阅读更多。
Home

以编程方式向 Visual Studio.Net 工具箱添加自定义控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.28/5 (11投票s)

Jan 13, 2005

CPOL

2分钟阅读

viewsIcon

130318

downloadIcon

798

本文的目的是简化以编程方式向 Visual Studio .Net 控件工具箱添加自定义控件的过程。

引言

本文的目的是简化以编程方式向 Visual Studio .NET 控件工具箱添加自定义控件的过程。

随附的示例将对组件开发人员有所帮助,他们希望以软件包的形式将其自定义控件部署给客户。 还有一个示例控制台应用程序,它演示了本文中介绍的技术。 此控制台应用程序可以通过带有参数的命令行运行,允许在安装期间启动它。

目前,支持以下 VS.NET 版本

  • VS.NET 2002
  • VS.NET 2003

背景

对于本文,需要对 Visual Studio .NET 和 C# 有基本的了解。 熟悉 DTE 和反射是一个加分项。

代码

此代码示例中有一个类,它提供一个名为 RegisterControls 的方法。 它接受两个参数

  • VS.NET 版本(使用 DTEVersion enum
  • 要添加的控件(使用 VSControl struct

DTE 代表设计时环境;它基本上是 VS.NET 的扩展性对象模型。

DTEVersion 是一个标志的 enum,它指定要使用的 VS.NET 版本。

[Flags]
public enum DTEVersion
{
                                          None      = 0x0000,
    [Description("VisualStudio.DTE.7")]   VS2002    = 0x0001,  //VS.Net 2002
    [Description("VisualStudio.DTE.7.1")] VS2003    = 0x0002,  //VS.Net 2003
}

VSControl struct 用于指定要添加哪些控件。

// Defines the name of the toolbox tab on which controls
// are located. If IsToolBoxTab is set true, a new toolbox
// tab will be created with the value of this field.
public string TabName;

// The path of the assembly which has controls in it.
public string ControlPath;

// The developer can give the type of the control,
// so the assembly path can be taken automatically.
public Type Control;

// If it is necessary to create a new toolbox tab,
// set IsToolBoxTab to true.
public bool IsToolBoxTab;

struct 具有三个构造函数,用于不同的目的

public VSControl(Type control, string tabName)

控件将被添加到指定的工具箱选项卡中。

public VSControl(string assemblyPath, string tabName)

程序集中的所有控件都将被添加到指定的工具箱选项卡中。

public VSControl(string tabGroupName)

将在工具箱中创建一个新的空选项卡。

RegisterControls 方法首先确定 DTE 的版本并获取一个合适版本的实例。

if((dteVersion & DTEVersion.VS2002) > DTEVersion.None)
{
    // Vs.Net 2002 is available
    dte = GetDesignTimeEnvironment(DTEVersion.VS2002, ref alreadyCreated;
    if(dte != null)
        RegisterControls(dte, alreadyCreated, controls);
    else
        return null;
}

GetDesignTimeEnvironment 函数返回 VS.NET 2002 或 VS.NET 2003 的实例。如果已经有实例在运行,则返回对该实例的引用。 如果未找到任何实例,则创建一个新实例。 当找到正在运行的实例时,下一步是确定工具箱是否可用。 当 VS.NET 运行时,无法将控件添加到工具箱中。

string progID = GetEnumDescription(dteVersion);
DTE result;
try
{
    // Determine if there is a running VS.Net instance
    result = (DTE) Marshal.GetActiveObject(progID);
    
    // Try to show properties window to see whether
    // Vs.Net is running a project
    try
    {
        // We have a running and usable Vs.Net instance
        result.ExecuteCommand("View.PropertiesWindow", "");
        alreadyCreated = true;
    }
    catch
    {
        // Running Vs.Net instance state is not usable
        // because it is running a project
        result = null;
    }
}
catch 
{
    // No running instances of Vs.Net is found
    result = null;
}

如果没有 Visual Studio .Net 的运行实例,或者现有实例不可用,我们创建一个新实例。

if(result == null)
{
    // Create a new VS.Net instance
    Type type = Type.GetTypeFromProgID(progID);
    if(type != null)
        result = (DTE) Activator.CreateInstance(type);
}

一旦我们拥有一个合适的 DTE,就会使用对所选 DTE 的引用调用 RegisterControls 方法。 在 RegisterControls 方法中,我们获取对工具箱窗口的引用,然后检索选项卡集合。

Window toolbox = dte.Windows.Item(EnvDTE.Constants.vsWindowKindToolbox);
ToolBoxTabs tabs = ((ToolBox) toolbox.Object).ToolBoxTabs;

根据开发人员的选择,在创建控件时,将添加一个新选项卡或使用现有选项卡。

tab = GetToolBoxTab(tabs, control.TabName);

if(tab != null &&  !control.IsToolBoxTab)
{
    tab.Activate();
    tab.ToolBoxItems.Item(1).Select();
    tab.ToolBoxItems.Add("MyControls", control.AssemblyPath, 
             vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);
}

在完成添加控件后,我们仅在我们创建 VS.NET 实例时才关闭它。

if(!alreadyCreatedDTE)
    dte.Quit();

可以快速构建一个控制台应用程序,该应用程序使用本文中的代码将控件轻松添加到工具箱中。

class Class1
{
    [STAThread]
    static void Main(string[] args)
    {
        string assemblyPath = @ "C:\Controls\SampleControls.dll";
        string tabName = "Sample Controls";

        VSControl sampleTabGroup = new VSControl(tabName);
        VSControl sampleControl1 = 
                        new VSControl(typeof(SampleControl), tabName);
        VSControl sampleControl2 = new VSControl(controlPath, tabName);
            
        bool result = DevEnvironment.RegisterControls(
            DTEVersion.VS2002 | DTEVersion.VS2003, 
            sampleTabGroup, 
            sampleControl1, 
            sampleControl2);
        
        if(result)
            Console.WriteLine("Controls added succesfully.");
        else
            Console.WriteLine(
                  "Controls couldn't be added. There is no VS.Net installed.");

        Console.WriteLine("Press any key to continue...");
        Console.ReadLine();
    }
}

可以扩展此示例控制台应用程序以接受来自命令提示符的参数,以便安装项目可以在安装期间运行它以添加指定的控件。

© . All rights reserved.