The Toolbox Window
The Toolbox stores controls and code snippets that you can drag onto the Forms Designer window, text editor windows, and anything else that can be a drag-and-drop target. The Toolbox is made up of a set of tabs where items can be stored and grouped into related categories. The items on a Toolbox tab are relatively static, but one tab, the Clipboard Ring, changes often and collects text that has been cut or copied from a text editor window.
Tabs and Items
To find the Toolbox window, you can pass the constant vsWindowKindToolbox to the Windows.Item method, which returns a Window object. The ToolBox object is then found by calling the returned object's Window.Object property, as shown here:
Sub FindTheToolBox()
Dim toolBoxWindow As EnvDTE.Window
Dim toolBox As EnvDTE.ToolBox
toolBoxWindow = DTE.Windows.Item(Constants.vsWindowKindToolbox)
toolBox = toolBoxWindow.Object
End Sub
Because the Toolbox can contain more than one tab, a collection is available to enumerate all these tabs. You find this collection, the ToolBoxTabs object, by calling the ToolBox.ToolBoxTabs property. Using the ToolBoxTabs collection, you can enumerate each ToolBoxTab object in the Toolbox and even create new tabs to house components or text fragments of your choosing. To create a new tab, you use the ToolBoxTabs.Add method, which takes as an argument the name of the new tab to create and returns a ToolBoxTab object for the newly created tab. The following macro adds a new Toolbox tab:
Sub AddNewToolBoxTab()
Dim toolBoxWindow As EnvDTE.Window
Dim toolBox As EnvDTE.ToolBox
toolBoxWindow = DTE.Windows.Item(Constants.vsWindowKindToolbox)
toolBox = toolBoxWindow.Object
toolBox.ToolBoxTabs.Add("My commonly used items").Activate()
End Sub
This code creates a new tab called My Commonly Used Items, and the Activate method of the ToolBoxTab object makes sure it's the selected tab.Not only is the Toolbox a collection of tabs, but each tab is also a collection of items. Each collection item is represented in the object model by a ToolBoxItem object and can be enumerated using the ToolBoxItems object, which is found by calling the ToolBoxTab.ToolBoxItems property. You can walk the entire contents of the Toolbox using the EnumerateToolBoxContents macro, shown here:
Sub EnumerateToolBoxContents()
Dim toolBoxWindow As EnvDTE.Window
Dim toolBox As EnvDTE.ToolBox
Dim toolBoxTab As ToolBoxTab
Dim outputWindow As New _
InsideVSNET.Utilities.OutputWindowPaneEx(DTE, "Toolbox contents")
toolBoxWindow = DTE.Windows.Item(Constants.vsWindowKindToolbox)
toolBox = toolBoxWindow.Object
For Each toolBoxTab In toolBox.ToolBoxTabs
Dim toolBoxItem As ToolBoxItem
outputWindow.WriteLine(toolBoxTab.Name)
For Each toolBoxItem In toolBoxTab.ToolBoxItems
outputWindow.WriteLine(vbTab + toolBoxItem.Name)
Next
Next
End Sub
Once you find a ToolBoxItem object, you'll see that you can't do much with it. You can call the Select method to make sure it's the active item in the Toolbox, you can remove the item using the Delete method, and you can find the label that's displayed in the user interface by using the Name property. Although the object model of a ToolBoxItem is a functional dead end, the real power that the Toolbox object model offers you is the ability to create new items.
Adding Items to the Toolbox
The Toolbox can hold different types of objects, such as text, HTML, COM components, and .NET components. You can add your own items by using the ToolBoxTab.Add method, which takes three parameters. The first parameter, Name, is the name of the item to add; this string is the text that will be displayed within the Toolbox user interface. The second parameter, Data, defines the information stored in the Toolbox for the item. How this data is formatted depends on the third parameter, Format, which is of type vsToolBoxItemFormat.The simplest data type that can be stored is raw text. The string passed to the Data parameter is copied verbatim into the Toolbox item, and when the text is dragged onto a window that supports drag-and-drop with a Clipboard format of type text (such as a text editor window), it is copied into that window. To add a text fragment, you can use code like this:
Sub AddTextToTheToolBox()
Dim toolBoxWindow As EnvDTE.Window
Dim toolBox As EnvDTE.ToolBox
Dim toolBoxTab As EnvDTE.ToolBoxTab
Dim toolBoxItems As EnvDTE.ToolBoxItems
toolBoxWindow = DTE.Windows.Item(Constants.vsWindowKindToolbox)
toolBox = toolBoxWindow.Object
toolBoxTab = toolBox.ToolBoxTabs.Item("General")
toolBoxItems = toolBoxTab.ToolBoxItems
toolBoxItems.Add("My Text", "This is some text", _
vsToolBoxItemFormat.vsToolBoxItemFormatText)
End Sub
This code starts by walking the object model and finding the General tab of the Toolbox. It ends by calling the ToolBoxItems.Add method and adding an item labeled My Text with the text This is some text that has the Clipboard format of type text.Adding text in the HTML format is similar to adding textthe differences are that rather than passing raw text, you need to pass a fragment of HTML code, and the format of the data is marked as HTML by using vsToolBoxItemFormatHTML:
Sub AddHTMLToTheToolBox()
Dim toolBoxWindow As EnvDTE.Window
Dim toolBox As EnvDTE.ToolBox
Dim toolBoxTab As EnvDTE.ToolBoxTab
Dim toolBoxItems As EnvDTE.ToolBoxItems
toolBoxWindow = DTE.Windows.Item(Constants.vsWindowKindToolbox)
toolBox = toolBoxWindow.Object
toolBoxTab = toolBox.ToolBoxTabs.Item("General")
toolBoxItems = toolBoxTab.ToolBoxItems
toolBoxItems.Add("My HTML", "<b>This is bold HTML</b>", _
vsToolBoxItemFormat.vsToolBoxItemFormatHTML)
End Sub
After you run this code, a fragment of HTML is placed onto the Toolbox; if you drag that Toolbox item into the HTML designer, text will appear in bold style.NoteRemember that HTML is really just an application of XML that follows a particular schema. Because HTML is XML, you can also store XML fragments as HTML on the Toolbox. Visual Studio .NET not only lets you drag-and-drop these HTML/XML fragments into an HTML document, but it also allows you to drag them into an XML document.Along with these two text formats, the Toolbox can also store ActiveX controls, which can be dragged onto HTML files or Win32 applications (such as an MFC dialog box) that support hosting ActiveX controls. To add an ActiveX control, you supply the vsToolBoxItemFormatGUID data type. The format of the Data argument is the CLSID GUID of the ActiveX control or (despite the name of the format type) the ProgID of the control. The following macro adds two copies of the Windows Media Player control to the Toolbox. The first one is added using the CLSID of the control, and the second is added based on its ProgID:
Sub AddCOMObjectToTheToolBox()
Dim toolBoxWindow As EnvDTE.Window
Dim toolBox As EnvDTE.ToolBox
Dim toolBoxTab As EnvDTE.ToolBoxTab
Dim toolBoxItems As EnvDTE.ToolBoxItems
toolBoxWindow = DTE.Windows.Item(Constants.vsWindowKindToolbox)
toolBox = toolBoxWindow.Object
toolBoxTab = toolBox.ToolBoxTabs.Item("General")
toolBoxItems = toolBoxTab.ToolBoxItems
toolBoxItems.Add("Name", "{22D6F312-B0F6-11D0-94AB-0080C74C7E95}", _
vsToolBoxItemFormat.vsToolBoxItemFormatGUID)
toolBoxItems.Add("Name", "MediaPlayer.MediaPlayer.1", _
vsToolBoxItemFormat.vsToolBoxItemFormatGUID)
End Sub
When you run this code, you'll notice that the Name parameter is ignored. This is because the Toolbox extracts the name from the control.The last type of item you can add to the Toolbox is a .NET Framework component. You use the vsToolBoxItemFormatDotNETComponent type format and supply the path location of a .NET assembly. That assembly is searched for controls, and if any are found, they're added to the Toolbox tab. For example, suppose you have an assembly called WindowsControlLibrary.dll at the root of your C: drive. The following code adds all the controls contained within that assembly to the Toolbox:
Sub AddDotNetComponentToTheToolBox()
Dim toolBoxWindow As EnvDTE.Window
Dim toolBox As EnvDTE.ToolBox
Dim toolBoxTab As EnvDTE.ToolBoxTab
Dim toolBoxItems As EnvDTE.ToolBoxItems
toolBoxWindow = DTE.Windows.Item(Constants.vsWindowKindToolbox)
toolBox = toolBoxWindow.Object
toolBoxTab = toolBox.ToolBoxTabs.Item("General")
toolBoxItems = toolBoxTab.ToolBoxItems
toolBoxItems.Add("Control", "C:\WindowsControlLibrary.dll", _
vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent)
End Sub
Often, an assembly that contains a control is placed into the global assembly cache (GAC) so it is available to all .NET Framework programs. Because the path to an assembly in the GAC isn't easy to find, you can load that assembly, ask it for its path, and then pass the path to the Toolbox add function. For example, suppose you have a user control with the assembly name WindowsControlLibrary, version number 1.0.795.38182, and a public key of 6fc70375761725c0. Using the System.Reflection.Assembly.Load static method, you can load the assembly by passing in the assembly name, version number, and public key. This method returns a System.Reflection.Assembly object, which supports a CodeBase property that returns the path in the file:/// format.
Sub AddDotNetComponentToTheToolBox2()
Dim toolBoxWindow As EnvDTE.Window
Dim toolBox As EnvDTE.ToolBox
Dim toolBoxTab As EnvDTE.ToolBoxTab
Dim toolBoxItems As EnvDTE.ToolBoxItems
Dim asm As System.Reflection.Assembly
toolBoxWindow = DTE.Windows.Item(Constants.vsWindowKindToolbox)
toolBox = toolBoxWindow.Object
toolBoxTab = toolBox.ToolBoxTabs.Item("General")
toolBoxItems = toolBoxTab.ToolBoxItems
asm = System.Reflection.Assembly.Load("WindowsControlLibrary1,
Version=1.0.795.38182, Culture=neutral, PublicKeyToken=6fc70375761725c0")
toolBoxItems.Add("Control", asm.CodeBase, _
vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent)
End Sub
Just as when you add an ActiveX control, when you add a .NET component to the Toolbox, the Name parameter is ignored and the name of the control is derived from the control itself. This might seem like a bug in Visual Studio .NET, but adding an assembly to the Toolbox differs slightly from adding the other formats. When you add text, HTML, or an ActiveX control, an EnvDTE.ToolBoxItem object for the newly added item is returned. However, when you add an assembly, a null or Nothing value (depending on the programming language used) is always returned. This is because an assembly can contain zero, one, or multiple controls. If the assembly contains zero controls, this null or Nothing return value makes sense because nothing was added and there's no ToolBoxItem object to return. Multiple items cannot be returned because the method returns only a single EnvDTE.ToolBoxItem object, not an array. If the assembly has only one control, it can return an EnvDTE.ToolBoxItem, but it would seem odd to return an item in this case and not in the others, so the design team decided to also return null or Nothing in this case.