This tip gives a solution to use font icons in most of WPF controls (like
I recently worked on using a ribbon in a WPF application. The problem is that the ribbon only permits to use
ImageSource to display icons.
My aim is to use a font icon library (like in HTML) because it contains vector icons and the final application is homogeneous.
In the sample, you will find the Font:
Using the Code
- Create a new WPF Project (can be MVVM).
- Create a ribbon (Add reference to
- Embed a font that will contain scalable icons:
- From your Resource.resx, add the ttf file
- In solution explorer, find the TTF file and change the "Build action" to "Resource"
- Add reference to
WpfTools (in download package)
- Use font icons as ImageSource
To display an icon from a font:
<RibbonButton Label="Import data"
FontFamily=/RibbonFontIconSample;component/Resources/#FontAwesome, Brush=Brown}" />
Use the following parameters:
Text: The character representing the icon (depending on the font. For
FontAwesome, I used
the CheatSheet http://fortawesome.github.io/Font-Awesome/cheatsheet/ to get code.
FontFamily to choose the embedded font (use the syntax below)
Brush used to colorize icon (can be a
Color or a
Style for italic
Weight for bold
Points of Interest
This class can be used with any controls which have an
ImageSource property (
It is a way to have high definition icons in application because they are scalable vector icons.
How It Works
As you cannot override
ImageSource one of the solutions is to create a
A markup extension is a class that can be used in
XAML code inside
and as only one pure
ProvideValue which is called to get the
public override object ProvideValue(IServiceProvider serviceProvider)
return CreateGlyph(Text, FontFamily, Style, Weight, Stretch, Brush);
In WPF, one way to render a
string as a drawable object is to use
glyph is a way to render one or more characters in a scalar way. It uses a Font and character index to draw one letter or icon.
Here is the code that draws a text into
private static ImageSource CreateGlyph(string text,
FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight,
FontStretch fontStretch, Brush foreBrush)
if (fontFamily != null && !String.IsNullOrEmpty(text))
Typeface typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);
if (!typeface.TryGetGlyphTypeface(out glyphTypeface))
throw new InvalidOperationException("No glyphtypeface found");
ushort glyphIndexes = new ushort[text.Length];
double advanceWidths = new double[text.Length];
for (int n = 0; n < text.Length; n++)
ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];
glyphIndexes[n] = glyphIndex;
double width = glyphTypeface.AdvanceWidths[glyphIndex] * 1.0;
advanceWidths[n] = width;
GlyphRun gr = new GlyphRun(glyphTypeface, 0, false, 1.0, glyphIndexes,
new Point(0, 0), advanceWidths,
null, null, null, null, null, null);
GlyphRunDrawing glyphRunDrawing = new GlyphRunDrawing(foreBrush, gr);
return new DrawingImage(glyphRunDrawing);
All the properties (
are not bindable (due to
MarkupExtension which is not a
The size is not directly managed, because the
glyph is rendered to stretch in the container object.
You have to put the class in a separate assembly (like
WpfTool) to make it work in design mode (it is a known bug of Visual Studio).