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






4.28/5 (11投票s)
本文的目的是简化以编程方式向 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();
}
}
可以扩展此示例控制台应用程序以接受来自命令提示符的参数,以便安装项目可以在安装期间运行它以添加指定的控件。