Specifying a Toolbox Icon for a Control in the WPF Designer
Recently I had a customer point out the following from the documentation:
Differences in Specifying Toolbox icons
In the Windows Forms Designer framework, you specify a Toolbox icon for your custom control by applying the ToolboxBitmapAttribute to your control class.
In the WPF Designer framework, you use an embedded resource and a naming convention to specify a Toolbox bitmap. In addition, you use the ToolboxBrowsableAttribute to restrict which types in an assembly are available for populating a Toolbox.
Followed by the question "What is the naming convention?"
I thought I'd answer that question by posting to my blog as it is not the first time I've had that question.
First, a note about the ToolboxBrowsableAttribute, it is defined in Microsoft.Windows.Design.dll so you don't want to use it declaratively in your code because that would require making a reference to Microsoft.Windows.Design.dll which will only be available on machines that have Visual Studio 2008 installed. Use the Metadata Store as discussed here and Metadata Assemblies as discussed here.
Toolbox Icon Naming Convention
- To add an image representing your control to a type, simply add an image at the same hierarchy and name in the project, and mark that image as an EmbeddedResource:
Cider will search for resources whose file name without extension matches the type name of the control, including the namespace with a “.icon[*].{BMP| PNG | GIF | JPG | JPEG}” .
- Note that folders in your project affect the namespace in which embedded resources are found.
- Supported extensions and file types are: BMP, GIF, JPG, JPEG and PNG
- Recommended image size for Bitmap based file formats is 64x64.
- The .icon[*] in the naming convention is optional and allows you to specify multiple sizes of the image that is used as the icon. The match follows the following algorithm:
- If there is an exact match on size (both dimensions) use it
- Use the closest match based on size and aspect ratio
- If a given resource file is not a valid image file, the next match will be used until one is found
Different hosts (i.e. Cider or Sparkle) use different image sizes for their toolbox icon.
- Sparkle uses 24x24 for their large size and 12x12 for their small size
- Cider (WPF Designer in Visual Studio) uses 16x16
This design will also be used to find a default icon for types added to the Collection Editor or Sub-Properties Editor “new instance” functionality.
Example:
Type is defined as:
namespace Proseware.Core.Controls
{
public partial class ProseControl : UserControl
{
public ProseControl()
{
InitializeComponent();
}
}
}
Default namespace: Proseware.Core.Controls
ProseControl.Icon.png is added as an Embedded Resource.
This causes the image at Proseware.Core.Controls.ProseControl.Icon.png from the resources inside the assembly in which ProseControl is contained to be used as the toolbox icon:
(view from reflector)
Multiple Sizes
The naming convention supports multiple image sizes. For the following example:
Type is defined as:
namespace Proseware.Core.Controls
{
public partial class ProseControl : UserControl
{
public ProseControl()
{
InitializeComponent();
}
}
}
Default namespace: Proseware.Core.Controls
For the ProseControl type, the following images in the resources will all be found and the best match for size will be used.
Proseware.Core.Controls.ProseControl.Icon.Large.png
Proseware.Core.Controls.ProseControl.Icon.Medium.png
Proseware.Core.Controls.ProseControl.Icon.ReallyLarge.png
Or, alternatively (the ‘.’ After Icon is not required but is acceptable):
Proseware.Core.Controls.ProseControl.IconLarge.png
Proseware.Core.Controls.ProseControl.IconMedium.png
Proseware.Core.Controls.ProseControl.IconReallyLarge.png
If the desired size by the host is 64 pixels by 64 pixels, and Proseware.Core.Controls.ProseControl.Icon.Large.png is the best match based on size and aspect ratio, it will be used. All of the images will be looked at.
If there are 2 images with the same size and aspect ratio, the host will decide which it will use.
Sample Project
Attached to this post is a sample project that illustrates how to get an icon defined for your control. To test, build the solution, right click on the toolbox and click "Choose Items...". Switch to the WPF Components tab and navigate to one of the control assemblies. You will then see your control with it's icon on the toolbox.
Comments
Anonymous
January 10, 2008
Hi Jim, Thanks for this -- very useful. This is working for me for displaying toolbox icons in Visual Studio, but I'm not seeing the custom icons in Expression Blend. I've tried your sample project as well, and Blend doesn't pick up the icons from that, so I'm not sure whether this is me being stupid or whether it's a Blend issue. I've tested with both Blend 1 and the Blend 2 December preview. Any suggestions? Thanks! IvanAnonymous
January 10, 2008
Hi Ivan, Blend did not implement this functionality. The only extensibility features that Blend supports is Metadata Loading, Licensing (needs the SDK), and Property Editing. JimAnonymous
March 11, 2015
The Control displays as ProseControl in toolbox. Is possible to change the control name, for example Prose instead of changing the class name.