Walkthrough: Customizing ToolboxItem Configuration Dynamically
This walkthrough shows how a managed VSPackage can supply dynamic configuration support for the ToolboxItem objects.
Note
The simplest way to add custom controls to the Toolbox is to use the Toolbox Control templates that are included in the Visual Studio SDK. This topic relates to advanced Toolbox development.
For more information about how to create toolbox controls by using the templates, see How to: Create a Toolbox Control That Uses Windows Forms and How to: Create a Toolbox Control That Uses WPF.
This walkthrough guides you through the following steps:
Add and correctly register all Toolbox controls in the VSPackage objects by using the ToolboxItemAttribute and ToolboxBitmapAttribute classes.
Create the following two controls and add icons for each of them to the Toolbox:
One control that declares an associated default ToolboxItem.
One control that declares an associated custom Toolbox item that is derived from the ToolboxItem class.
Write an implementation of IConfigureToolboxItem, and register it by doing the following things:
Defining a filter class that derives from the IConfigureToolboxItem class and specifies the ToolboxItem instances that this implementation will act on.
Applying a ProvideToolboxItemConfigurationAttribute, which references the filter class, to the class that implements the Package class for the VSPackage.
Register the VSPackage as a provider of ToolboxItem objects by applying the ProvideToolboxItemsAttribute to the class that implements the Package class for the VSPackage.
At package load time, use reflection to generate a list of all ToolboxItem objects that the VSPackage provides.
Create a handler for the ToolboxInitialized and ToolboxUpgraded events. Doing this guarantees that the VSPackage's ToolboxItem objects are correctly loaded.
Implement a command on the VSPackage to force re-initialization of the Toolbox.
Prerequisites
To follow this walkthrough, you must install the Visual Studio 2013 SDK. For more information, see Visual Studio Software Development Kit (SDK).
Locations for the Visual Studio Package Project Template
The Visual Studio Package project template can be found in three different locations in the New Project dialog:
Under Visual Basic Extensibility. The default language of the project is Visual Basic.
Under C# Extensibility. The default language of the project is C#.
Under Other Project Types Extensibility. The default language of the project is C++.
Creating a Managed VSPackage
Complete the following procedures to create a managed VSPackage.
To create a managed VSPackage to provide toolbox items
Create a VSPackage named ItemConfiguration. For more information, see Walkthrough: Creating a Menu Command By Using the Visual Studio Package Template.
In the Visual Studio Package template, add a menu command.
Name the command Initialize ItemConfigurationVB for Visual Basic or Initialize ItemConfigurationCS for Visual C#.
For Visual Basic, add the following namespaces to the imported namespaces list in the generated project:
Company.ItemConfiguration
System
System.ComponentModel
System.Drawing
System.Windows.Forms
Add a reference to the System.Drawing.Design .NET Framework component.
If you follow this walkthrough for more than one language, you must update the project to disambiguate the generated assemblies.
To disambiguate Visual Basic and Visual C# VSPackages
For Visual Basic:
Open the project properties, and select the Application tab.
Change the assembly name to ItemConfigurationVB, and change the default namespace to Company.ItemConfigurationVB.
Select the References tab.
Update the imported namespaces list.
Remove Company.ItemConfiguration.
Add Company.ItemConfigurationVB.
For Visual C#:
Open the project properties, and select the Application tab.
Change the assembly name to ItemConfigurationCS, and change the default namespace to Company.ItemConfigurationCS.
Open the ItemConfigurationPackage class in the code editor.
To use the refactoring tools to rename the existing namespace, right-click the existing namespace name, ItemConfiguration, point to Refactor, and then click Rename. Change the name to ItemConfigurationCS.
Save all changes.
To test the generated code
Compile and start the VSPackage in the Visual Studio experimental hive.
On the Tools menu, click Initialize Item Configuration VB or Initialize Item Configuration CS.
Doing this opens a message box that contains text that indicates that the package's menu item handler was called.
Close the experimental version of Visual Studio.
Creating Toolbox Controls
In this section, you create and register a user control, Control1, that declares an associated default Toolbox item. You also create and register a second user control, Control2, and an associated custom Toolbox item, Control2_ToolboxItem, that is derived from the ToolboxItem class. For more information about how to author Windows Forms controls and ToolboxItem classes, see Developing Windows Forms Controls at Design Time.
To create default and custom toolbox items
Use the instructions in Walkthrough: Autoloading Toolbox Items to create a default Toolbox item and a custom Toolbox item, as follows.
Complete the procedure, "To create a Toolbox control that will be used with a default ToolboxItem." Update the DescriptionAttribute to reference this project.
The resulting code for the Control1 class should resemble the following code.
' Set the display name and custom bitmap to use for this item. ' The build action for the bitmap must be "Embedded Resource". <DisplayName("ToolboxMember 1 VB")> _ <Description("Custom toolbox item from package ItemConfiguration.")> _ <ToolboxItem(True)> _ <ToolboxBitmap(GetType(Control1), "Control1.bmp")> _ Public Class Control1 Public Sub New() InitializeComponent() Button1.Text = Me.Name + " Button" End Sub Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click MessageBox.Show("Hello world from " & Me.ToString()) End Sub End Class
using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace Company.ItemConfigurationCS { // Set the display name and custom bitmap to use for this item. // The build action for the bitmap must be "Embedded Resource". [DisplayName("ToolboxMember 1 CS")] [Description("Custom toolbox item from package ItemConfiguration.")] [ToolboxItem(true)] [ToolboxBitmap(typeof(Control1), "Control1.bmp")] public partial class Control1 : UserControl { public Control1() { InitializeComponent(); button1.Text = this.Name + " Button"; } private void button1_Click(object sender, EventArgs e) { MessageBox.Show("Hello world from " + this.ToString()); } } }
Complete the procedure, "To create a Toolbox control for using a custom ToolboxItem-derived class." Update the DescriptionAttribute to reference this project.
The resulting code for the Control2 and Control2_ToolboxItem classes should resemble the following code.
Imports System.Drawing.Design Imports System.Globalization ' Set the display name and custom bitmap to use for Me item. ' The build action for the bitmap must be "Embedded Resource". ' Also declare a custom toolbox item implementation. <DisplayName("ToolboxMember 2 VB")> _ <Description("Custom toolbox item from package ItemConfiguration.")> _ <ToolboxItem(GetType(Control2_ToolboxItem))> _ <ToolboxBitmap(GetType(Control2), "Control2.bmp")> _ Public Class Control2 Public Sub New() InitializeComponent() Button1.Text = Me.Name + " Button" End Sub Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click MessageBox.Show("Hello world from " & Me.ToString()) End Sub End Class <Serializable()> _ Friend Class Control2_ToolboxItem Inherits ToolboxItem Public Sub New(ByVal toolType As Type) MyBase.New(toolType) End Sub Public Overrides Sub Initialize(ByVal toolType As Type) If Not toolType.Equals(GetType(Control2)) Then Throw New ArgumentException( _ String.Format(CultureInfo.CurrentCulture, _ "The {0} constructor argument must be of type {1}.", _ Me.GetType().FullName, GetType(Control2).FullName)) End If MyBase.Initialize(toolType) End Sub End Class
using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Drawing.Design; using System.Globalization; namespace Company.ItemConfigurationCS { // Set the display name and custom bitmap to use for this item. // The build action for the bitmap must be "Embedded Resource". // Also declare a custom toolbox item implementation. [DisplayName("ToolboxMember 2 CS")] [Description("Custom toolbox item from package ItemConfigurationPackage.")] [ToolboxItem(typeof(Control2_ToolboxItem))] [ToolboxBitmap(typeof(Control2), "Control2.bmp")] public partial class Control2 : UserControl { public Control2() { InitializeComponent(); button1.Text = this.Name + " Button"; } private void button1_Click(object sender, EventArgs e) { MessageBox.Show("Hello world from " + this.ToString()); } } [Serializable()] internal class Control2_ToolboxItem : ToolboxItem { public Control2_ToolboxItem(Type toolType) : base(toolType) { } public override void Initialize(Type toolType) { if (!toolType.Equals(typeof(Control2))) { throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, "The {0} constructor argument must be of type {1}.", this.GetType().FullName, typeof(Control2).FullName)); } base.Initialize(toolType); } } }
Save the files.
Embedding Bitmap Icons
The ToolboxBitmapAttribute attribute that is applied to each control specifies which icon to associate with that control. Create the bitmaps for both controls, and name them as follows:
Control1.bmp, for the Control1 class.
Control2.bmp, for the Control2 class.
To embed a bitmap icon for a Toolbox item
Add a new bitmap to the project, as follows:
In Solution Explorer, right-click the VSPackage project, point to Add, and then click New Item.
In the Add New Item dialog box, select Bitmap File, and enter the name of the bitmap.
Use the bitmap editor to create a 16x16 icon, as follows.
On the View menu, click Properties Window.
In the Properties window, set Height and Width to 16.
Use the editor to create the icon image.
In Solution Explorer, right-click the bitmap item, and then click Properties.
Set the Build Action property to Embedded Resource.
Save all open files.
Adding a Dynamic Toolbox Configuration Provider
In this section, you create and register a class that implements the IConfigureToolboxItem interface. This class is instantiated and used by the Visual Studio integrated development environment (IDE) to configure Toolbox controls.
Note
Because the Visual Studio environment instantiates an instance of the implementation of IConfigureToolboxItem, do not implement the IConfigureToolboxItem interface on the class that implements Package for a VSPackage.
To create and register a toolbox control configuration object
In Solution Explorer, add a class to the ItemConfiguration project, and name it ToolboxConfig.
Add the following namespace statements to the file.
Imports Microsoft.VisualStudio.Shell Imports System.Collections Imports System.ComponentModel Imports System.Drawing.Design Imports System.Reflection Imports System.Runtime.InteropServices Imports System.Security.Permissions
using Microsoft.VisualStudio.Shell; using System.Collections; using System.ComponentModel; using System.Drawing.Design; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Permissions;
Ensure that the ToolboxConfig class is public and implements the IConfigureToolboxItem interface.
Apply a GuidAttribute and a ProvideAssemblyFilterAttribute to the ToolboxConfig class.
For Visual Basic, use an assembly name of "ItemConfigurationVB, Version=*, Culture=*, PublicKeyToken=*".
For Visual C#, use an assembly name of "ItemConfigurationCS, Version=*, Culture=*, PublicKeyToken=*".
Doing this restricts the ToolboxConfig class to working on ToolboxItem objects that are provided by the assembly that contains the current VSPackage.
<ProvideAssemblyFilter("ItemConfigurationVB, Version=*, Culture=*, PublicKeyToken=*")> _ <Guid("4DDC7895-442A-45e7-82E7-4E85F243C321")> _ Public Class ToolboxConfig Implements IConfigureToolboxItem
[ProvideAssemblyFilter("ItemConfigurationCS, Version=*, Culture=*, PublicKeyToken=*")] [Guid("E6832593-BF07-4de1-AA0F-7F9B94887DB8")] public class ToolboxConfig : IConfigureToolboxItem
You can generate a GUID by clicking Create GUID on the Tools menu. Select the format with square braces, click Copy, and then paste the GUID in your code. change the keyword GUID to Guid.
Implement the ConfigureToolboxItem method of the IConfigureToolboxItem interface so that the method only acts on the two ToolboxItem classes, Control1 and Control2.
The implementation of ConfigureToolboxItem applies instances of ToolboxItemFilterAttribute to the two ToolboxItem objects so that:
The ToolboxItem that is implemented by Control1 is only available in the Toolbox for designers that handle UserControl objects.
The ToolboxItem that is implemented by Control2 is not available in the Toolbox for designers that handle UserControl objects.
<PrincipalPermission(SecurityAction.Demand)> Public Sub _ ConfigureToolboxItem(ByVal item As ToolboxItem) _ Implements IConfigureToolboxItem.ConfigureToolboxItem If item Is Nothing Then Return ' Create a filter for the Toolbox. Dim newFilter As ToolboxItemFilterAttribute If GetType(Control1).ToString() = item.TypeName Then ' For Control1, only show it when editing a UserControl. newFilter = New ToolboxItemFilterAttribute( _ "System.Windows.Forms.UserControl", _ ToolboxItemFilterType.Require) ElseIf GetType(Control2).ToString() = item.TypeName Then ' For Control2, only show it when not editing a UserControl. newFilter = New ToolboxItemFilterAttribute( _ "System.Windows.Forms.UserControl", _ ToolboxItemFilterType.Prevent) Else ' Don't apply a filter to other classes. Return End If item.Filter = CType(New ToolboxItemFilterAttribute() {newFilter}, ICollection) End Sub
[PrincipalPermission(SecurityAction.Demand)] public void ConfigureToolboxItem(ToolboxItem item) { if (null == item) return; // Create a filter for the Toolbox. ToolboxItemFilterAttribute newFilter; if (typeof(Control1).ToString() == item.TypeName) { // For Control1, only show it when editing a UserControl. newFilter = new ToolboxItemFilterAttribute( "System.Windows.Forms.UserControl", ToolboxItemFilterType.Require); } else if (typeof(Control2).ToString() == item.TypeName) { // For Control2, only show it when not editing a UserControl. newFilter = new ToolboxItemFilterAttribute( "System.Windows.Forms.UserControl", ToolboxItemFilterType.Prevent); } else { // Don't apply a filter to other classes. return; } item.Filter = (ICollection)(new ToolboxItemFilterAttribute[] { newFilter }); }
Modifying the VSPackage Implementation
The default implementation of the VSPackage that is provided by the Visual Studio Package template must be modified to do the following things:
Register as a Toolbox item provider.
Register the class that provides the dynamic Toolbox control configuration for the VSPackage.
Use the ToolboxService to load all the ToolboxItem objects that are provided by the VSPackage assembly.
Handle ToolboxInitialized and ToolboxUpgraded events.
To modify the Package implementation for a Toolbox item provider on the VSPackage
Open the ItemConfigurationPackage class in the code editor.
Modify the declaration of the ItemConfigurationPackage class, which is the implementation of the Package class in the solution.
Add the following namespace statements to the file.
Imports System.Collections Imports System.ComponentModel Imports System.Drawing.Design Imports System.Reflection
using System.Collections; using System.ComponentModel; using System.Drawing.Design; using System.Reflection;
To register the VSPackage as providing Toolbox items, apply a ProvideToolboxItemsAttribute to the package. To register the ToolboxConfig class as providing a Toolbox control dynamic configuration, apply a ProvideToolboxItemConfigurationAttribute to the package.
' ... <PackageRegistration(UseManagedResourcesOnly:=True), _ DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0"), _ InstalledProductRegistration(False, "#110", "#112", "1.0", IconResourceID:=400), _ ProvideLoadKey("Standard", "1.0", "Package Name", "Company", 1), _ ProvideMenuResource(1000, 1), _ Guid(GuidList.guidItemConfigurationPkgString)> _ <ProvideToolboxItems(1)> _ <ProvideToolboxItemConfiguration(GetType(ToolboxConfig))> _ Public NotInheritable Class DynamicToolboxMembersPackage Inherits Package
// ... [PackageRegistration(UseManagedResourcesOnly = true)] // ... [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")] // ... [InstalledProductRegistration(false, "#110", "#112", "1.0", IconResourceID = 400)] // ... [ProvideLoadKey("Standard", "1.0", "Package Name", "Company", 1)] // ... [ProvideMenuResource(1000, 1)] [Guid(GuidList.guidItemConfigurationPkgString)] [ProvideToolboxItems(1)] [ProvideToolboxItemConfiguration(typeof(ToolboxConfig))] public sealed class DynamicToolboxMembersPackage : Package
Note
The only argument of ProvideToolboxItemsAttribute is the version of ToolboxItem that is provided by the VSPackage. By changing this value, you force the IDE to load the VSPackage even if it has an earlier cached version of ToolboxItem.
Create two new private fields in the ItemConfiguration class, as follows:
An ArrayList member, named ToolboxItemList, to hold a list of the ToolboxItem objects that the ItemConfiguration class manages.
A String, named CategoryTab, that contains the Toolbox tab that is used to hold the ToolboxItem objects that the ItemConfiguration class manages.
Private ToolboxItemList As ArrayList Private Shared ReadOnly CategoryTab As String = _ "ItemConfiguration Walkthrough VB"
private ArrayList ToolboxItemList; private static readonly string CategoryTab = "ItemConfiguration Walkthrough CS";
The result of this modification resembles the following code:
Imports Microsoft.VisualBasic Imports System Imports System.Diagnostics Imports System.Globalization Imports System.Runtime.InteropServices Imports System.ComponentModel.Design Imports Microsoft.Win32 Imports Microsoft.VisualStudio.Shell.Interop Imports Microsoft.VisualStudio.OLE.Interop Imports Microsoft.VisualStudio.Shell Imports System.Collections Imports System.ComponentModel Imports System.Drawing.Design Imports System.Reflection ' ... <PackageRegistration(UseManagedResourcesOnly:=True), _ DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0"), _ InstalledProductRegistration(False, "#110", "#112", "1.0", IconResourceID:=400), _ ProvideLoadKey("Standard", "1.0", "Package Name", "Company", 1), _ ProvideMenuResource(1000, 1), _ Guid(GuidList.guidItemConfigurationPkgString)> _ <ProvideToolboxItems(1)> _ <ProvideToolboxItemConfiguration(GetType(ToolboxConfig))> _ Public NotInheritable Class DynamicToolboxMembersPackage Inherits Package Private ToolboxItemList As ArrayList Private Shared ReadOnly CategoryTab As String = _ "ItemConfiguration Walkthrough VB" ' ...
using System; using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; using System.ComponentModel.Design; using Microsoft.Win32; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Shell; using System.Collections; using System.ComponentModel; using System.Drawing.Design; using System.Reflection; namespace Company.ItemConfigurationCS { // ... [PackageRegistration(UseManagedResourcesOnly = true)] // ... [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")] // ... [InstalledProductRegistration(false, "#110", "#112", "1.0", IconResourceID = 400)] // ... [ProvideLoadKey("Standard", "1.0", "Package Name", "Company", 1)] // ... [ProvideMenuResource(1000, 1)] [Guid(GuidList.guidItemConfigurationPkgString)] [ProvideToolboxItems(1)] [ProvideToolboxItemConfiguration(typeof(ToolboxConfig))] public sealed class DynamicToolboxMembersPackage : Package { private ArrayList ToolboxItemList; private static readonly string CategoryTab = "ItemConfiguration Walkthrough CS"; // ...
Define an OnRefreshToolbox method to handle the ToolboxInitialized and ToolboxUpgraded events.
The OnRefreshToolbox method uses the list of ToolboxItem objects that is contained in the ToolboxItemList field and does the following things:
Removes all ToolboxItem objects from the Toolbox tab that is defined by the CategoryTab field.
Adds to the Toolbox tab new instances of all ToolboxItem objects that are listed in the ToolboxItemList field.
Sets the Toolbox tab as the active tab.
' Add new instances of all ToolboxItems to the toolbox item list. Private Sub OnRefreshToolbox(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.ToolboxInitialized, Me.ToolboxUpgraded Dim service As IToolboxService = _ TryCast(GetService(GetType(IToolboxService)), IToolboxService) Dim toolbox As IVsToolbox = _ TryCast(GetService(GetType(IVsToolbox)), IVsToolbox) ' Remove target tab and all items under it. For Each item As ToolboxItem In service.GetToolboxItems(CategoryTab) service.RemoveToolboxItem(item) Next toolbox.RemoveTab(CategoryTab) ' Recreate the target tab with the items from the current list. For Each item As ToolboxItem In ToolboxItemList service.AddToolboxItem(item, CategoryTab) Next service.SelectedCategory = CategoryTab service.Refresh() End Sub
// Add new instances of all ToolboxItems to the toolbox item list. void OnRefreshToolbox(object sender, EventArgs e) { IToolboxService service = GetService(typeof(IToolboxService)) as IToolboxService; IVsToolbox toolbox = GetService(typeof(IVsToolbox)) as IVsToolbox; // Remove target tab and all items under it. foreach (ToolboxItem item in service.GetToolboxItems(CategoryTab)) { service.RemoveToolboxItem(item); } toolbox.RemoveTab(CategoryTab); // Recreate the target tab with the items from the current list. foreach (ToolboxItem item in ToolboxItemList) { service.AddToolboxItem(item, CategoryTab); } service.SelectedCategory = CategoryTab; service.Refresh(); }
For Visual C#, in the constructor, register the OnRefreshToolbox method as the event hander for the ToolboxInitialized and ToolboxUpgraded events.
this.ToolboxInitialized += new EventHandler(OnRefreshToolbox); this.ToolboxUpgraded += new EventHandler(OnRefreshToolbox);
Modify the Initialize method in ItemConfigurationPackage to fill the ToolboxItemList field by calling the GetToolboxItems method of the ToolboxService class. The Toolbox service gets all the Toolbox item classes that are defined in the currently executing assembly. The ToolboxItemList field is used by the Toolbox event handlers to load the Toolbox items.
Add the following code at the end of the Initialize method.
' Use the toolbox service to get a list of all toolbox items in ' this assembly. ToolboxItemList = New ArrayList( _ ToolboxService.GetToolboxItems(Me.GetType().Assembly, "")) If ToolboxItemList Is Nothing Then Throw New ApplicationException( _ "Unable to generate a toolbox item listing for " & _ Me.GetType().FullName) End If ' Update the display name of each toolbox item in the list. Dim thisAssembly As Assembly = Me.GetType().Assembly For Each item As ToolboxItem In ToolboxItemList Dim underlyingType As Type = thisAssembly.GetType(item.TypeName) Dim attribs As AttributeCollection = _ TypeDescriptor.GetAttributes(underlyingType) Dim displayName As DisplayNameAttribute = _ TryCast(attribs(GetType(DisplayNameAttribute)), DisplayNameAttribute) If displayName IsNot Nothing AndAlso Not displayName.IsDefaultAttribute() Then item.DisplayName = displayName.DisplayName End If Next
// Use the toolbox service to get a list of all toolbox items in // this assembly. ToolboxItemList = new ArrayList( ToolboxService.GetToolboxItems(this.GetType().Assembly, "")); if (null == ToolboxItemList) { throw new ApplicationException( "Unable to generate a toolbox item listing for " + this.GetType().FullName); } // Update the display name of each toolbox item in the list. Assembly thisAssembly = this.GetType().Assembly; foreach (ToolboxItem item in ToolboxItemList) { Type underlyingType = thisAssembly.GetType(item.TypeName); AttributeCollection attribs = TypeDescriptor.GetAttributes(underlyingType); DisplayNameAttribute displayName = attribs[typeof(DisplayNameAttribute)] as DisplayNameAttribute; if (displayName != null && !displayName.IsDefaultAttribute()) { item.DisplayName = displayName.DisplayName; } }
Note
As an exercise, one could develop a mechanism for testing the version of the VSPackage or the items, and only update if the VSPackage version has changed or if the version of the ToolboxItem has changed.
Initializing the Toolbox
To implement a command to initialize the Toolbox
In the ItemConfigurationPackage class, change the MenuItemCallBack method, which is the menu item's command handler.
Replace the existing implementation of the MenuItemCallBack method by using the following code:
Private Sub MenuItemCallback(ByVal sender As Object, ByVal e As EventArgs) Dim pkg As IVsPackage = TryCast(GetService(GetType(Package)), IVsPackage) pkg.ResetDefaults(CUInt(__VSPKGRESETFLAGS.PKGRF_TOOLBOXITEMS)) End Sub
private void MenuItemCallback(object sender, EventArgs e) { IVsPackage pkg = GetService(typeof(Package)) as IVsPackage; pkg.ResetDefaults((uint)__VSPKGRESETFLAGS.PKGRF_TOOLBOXITEMS); }
Building and Running the Solution
You can exercise the product of this walkthrough by using an instance of Visual Studio that is running in the experimental hive.
To exercise this walkthrough
In Visual Studio, on the Build menu, click Rebuild Solution.
Press F5 to start a second instance of Visual Studio in the experimental registry hive.
For more information about how to use the experimental hive, see Experimental Instance of Visual Studio.
Click the Tools menu.
A command named Initialize ItemConfiguration VB or Initialize ItemConfiguration CS appears at the top of the menu, together with an icon that has the numeral 1.
Create a new Visual C# or Visual Basic Windows Forms application.
A Form-based designer appears.
Add a user control to the project.
A user control designer appears.
Pin the Toolbox open, and switch between the two design views.
Notice that which Toolbox item is visible and which one is hidden depends on which designer has focus.
Drag the first Toolbox item onto the user control to add an instance of Control1 to the user control.
Drag the second Toolbox item onto the form to add an instance of Control2 to the form.
Build the Windows application.
The user control for the application is now available in the Toolbox.
Add the application's user control to the form, and then rebuild the application and run it.
When the application runs, click each control on the form to get the associated message box.
Analysis of the Implementation
Because the assemblyFilter parameter is present in the ProvideAssemblyFilterAttribute class constructor, only ToolboxItem objects in the assembly produced in this walkthrough are acted on by the ConfigureToolboxItem method of the ToolboxConfg class.
Therefore, whenever the ItemConfiguration Walkthrough category is active on the Toolbox, the ConfigureToolboxItem method of the ToolboxConfg class is called, and ToolboxItemFilterAttribute instances are applied on the ToolboxItem objects that are implemented by Control1 and Control2.
See Also
Tasks
Advanced Toolbox Control Development
Concepts
Registering Toolbox Support Features