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

  1. 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:

  1. 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}” . 

    1. Note that folders in your project affect the namespace in which embedded resources are found.
    2. Supported extensions and file types are: BMP, GIF, JPG, JPEG and PNG
    3. Recommended image size for Bitmap based file formats is 64x64.
    4. 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:
      1. If there is an exact match on size (both dimensions) use it
      2. Use the closest match based on size and aspect ratio
    5. If a given resource file is not a valid image file, the next match will be used until one is found
  2. Different hosts (i.e. Cider or Sparkle) use different image sizes for their toolbox icon. 

    1. Sparkle uses 24x24 for their large size and 12x12 for their small size
    2. Cider (WPF Designer in Visual Studio) uses 16x16
  3. 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.

ToolboxIconSample.zip