Known Issue: Controls and GAC, Toolbox and TCI
Introduction
The purpose of the post is to provide guidance for control authors to limit the controls added to the Toolbox and that are listed in the Choose Items Dialog.
The word "controls" in this post is defined as "any public type in a control assembly that derives from FrameworkElement or above." Both the TCI and Choose Items Dialog include all public types that derive from FrameworkElement or above.
Does This Information Apply To My Control Assemblies?
If your control assemblies are installed in the GAC and you want to limit controls visible in the Choose Items Dialog you must follow the guidance in this post.
If you use the TCI to have Visual Studio install your controls in the Toolbox and you install your control assemblies in the GAC and want to limit controls installed into the Toolbox and controls visible in the Choose Items Dialog you must follow the guidance in this post.
If you use the TCI to have Visual Studio install your controls in the Toolbox, you must have a design-time assembly to limit controls installed in the Toolbox. This applies to both WPF & Silverlight controls.
This post covers two known issues.
- WPF only. Public types in control assemblies installed in the GAC that derive from FrameworkElement or above are now required to be decorated with the System.ComponentModel.DesignTimeVisible(false) attribute in order to keep the type from appearing in the Toolbox or the Choose Items Dialog. Not decorating the type with this attribute, could result in the type being added to the Toolbox and will result in the type being listed in the Choose Items Dialog.
- WPF and Silverlight. Control assemblies that are installed using the TCI require a design-time assembly to limit the types added to the Toolbox and the Choose Items Dialog. Without the design-time assembly, all types deriving from FrameworkElement or above will be placed in the Toolbox and will be listed in the Choose Items Dialog.
Critical |
If a control assembly is installed into the GAC and uses the TCI, you must implement both of the above steps to keep unwanted types out of the Toolbox and Choose Items. |
Scenario Assemblies
The following two WPF assemblies are assumed for this post.
- C:\Acme\Acme.Controls.dll
- C:\Acme\Acme.Controls.Design.dll
Acme.Controls.dll
Each of the below four custom controls has a two line summary comment. The first line of the comment describes what if any metadata is associated with the control in the design assembly. The second line applies to the control itself. The name of the control describes when the control will be visible.
namespace Acme.Controls {
/// <summary>
/// This control has a design assembly ToolboxBrowsableAttribute false.
/// This attribute only gets processed when this assembly is in the GAC.
/// </summary>
[DesignTimeVisible(false)]
public class YouShouldNeverSeeMe : Control {
}
/// <summary>
/// This control has a design assembly ToolboxBrowsableAttribute true.
/// This control will be in the Toolbox and Choose Items.
/// </summary>
public class ToolboxBrowsableAttributeTrue : Control {
}
/// <summary>
/// This control has a design assembly ToolboxBrowsableAttribute false.
/// This control will not be in the Toolbox or Choose Items unless this assembly is loaded in the GAC.
/// </summary>
public class OnlyShowsInChooseItemsWhenInGAC : Control {
}
/// <summary>
/// This control does NOT have a design assembly ToolboxBrowsableAttribute.
/// WARNING: This control will always be loaded in the Toolbox and will be visible in Choose Items.
/// </summary>
public class FrameworkElementAlwaysShows : FrameworkElement {
}
}
Acme.Controls.Design.dll
The below design assembly applies to the above control assembly.
The ToolboxBrowsableAttribute can be created two ways, both syntaxs create the required attribute:
- ToolboxBrowsableAttribute.Yes is the same as new ToolboxBrowsableAttribute(true)
- ToolboxBrowsableAttribute.No is the same as new ToolboxBrowsableAttribute(false)
//This should be in AssemblyInfo.cs - declaring here to make it obvious
//This attribute is used to determine which class to load to register metadata
[assembly: ProvideMetadata(typeof(Acme.Controls.Design.RegisterMetadata))]
namespace Acme.Controls.Design {
internal class RegisterMetadata : IProvideAttributeTable {
public Microsoft.Windows.Design.Metadata.AttributeTable AttributeTable {
get {
AcmeControlsAttributeTableBuilder obj = new AcmeControlsAttributeTableBuilder();
return obj.CreateTable();
}
}
}
class AcmeControlsAttributeTableBuilder : AttributeTableBuilder {
public AcmeControlsAttributeTableBuilder() {
AddTypeAttributes(typeof(ToolboxBrowsableAttributeTrue), ToolboxBrowsableAttribute.Yes);
AddTypeAttributes(typeof(OnlyShowsInChooseItemsWhenInGAC), ToolboxBrowsableAttribute.No);
AddTypeAttributes(typeof(YouShouldNeverSeeMe), ToolboxBrowsableAttribute.No);
}
void AddTypeAttributes(Type type, params Attribute[] attribs) {
base.AddCallback(type, builder => builder.AddCustomAttributes(attribs));
}
}
}
Scenario: TCI Toolbox Install
AssemblyFoldersEx Registry Entry
The following two registry entries will install the controls into the Toolbox under the Acme Toolbox tab.
[HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0\AssemblyFoldersEx\Acme]
@="c:\\Acme\\"
[HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0\AssemblyFoldersEx\Acme\Toolbox]
TabName="Acme"
How to Limit Types in the Toolbox and Choose Items Dialog when the Assembly is Not in the GAC
In the design assembly, add the ToolboxBrowsableAttribute.No to a public control assembly type's metadata to hide it.
How to Limit Types in the Toolbox and Choose Items Dialog when the Assembly is in the GAC
In the design assembly, add the ToolboxBrowsableAttribute.No to a public control assembly type's metadata to hide it.
In the control assembly, decorate public types with the DesignTimeVisible(false)attribute to hide it.
Scenario: No TCI, Just Choose Items Dialog
How to Limit Types in the Toolbox and Choose Items Dialog when the Assembly is Not in the GAC
In the design assembly, add the ToolboxBrowsableAttribute.No to a public control assembly type's metadata to hide it.
How to Limit Types in the Toolbox and Choose Items Dialog when the Assembly is in the GAC
In the design assembly, add the ToolboxBrowsableAttribute.No to a public control assembly type's metadata to hide it.
In the control assembly, decorate public types with the DesignTimeVisible(false)attribute to hide it.
Comments
Microsoft values your opinion about our products and documentation. In addition to your general feedback it is very helpful to understand:
- How the above features enable your workflow
- What is missing from the above feature that would be helpful to you
Thank you for your feedback and have a great day,
Karl Shifflett
Visual Studio Cider Team