Click here to Skip to main content
15,883,809 members
Articles / Desktop Programming / WPF
Tip/Trick

Using Font Icons

Rate me:
Please Sign up or sign in to vote.
5.00/5 (12 votes)
12 Aug 2013CPOL2 min read 65.7K   2.9K   24   7
This tip helps in using font icons as ImageSource.

Introduction

This tip gives a solution to use font icons in most of WPF controls (like Ribbon).

Image 1

Background

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

  1. Create a new WPF Project (can be MVVM).
  2. Create a ribbon (Add reference to System.Windows.Controls.Ribbon).
  3. Embed a font that will contain scalable icons:
    1. From your Resource.resx, add the ttf file
    2. In solution explorer, find the TTF file and change the "Build action" to "Resource"
  4. Add reference to WpfTools (in download package)
  5. Use font icons as ImageSource

To display an icon from a font:

XML
<RibbonButton Label="Import data" 
  LargeImageSource="{WpfTools:ImageFromFont Text=&#xf01a;, 
  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 static resource)
  • Style for italic
  • Weight for bold

Points of Interest

This class can be used with any controls which have an ImageSource property (Ribbon, Image, ...).

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 MarkupExtension.

A markup extension is a class that can be used in XAML code inside { } and as only one pure abstract method ProvideValue which is called to get the resulting object.

C#
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 (and GlyphRun).

A 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 ImageSource:

C#
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);
        GlyphTypeface glyphTypeface;
        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);

    }
    return null;
}

Limitations

All the properties (Text, FontFamily, Brush) are not bindable (due to MarkupExtension which is not a DependencyObject).

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).

History

  • 08/2013: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer ECT Industries
France France
I am software engineer and I work for the aviation.

I'm currently working on many different project and in many different languages
- Visual C++ 6
- C#
- ASP.NET
- C and assembly

Have lot of fun

Comments and Discussions

 
QuestionSmall Icon Images Pin
JAbedinejad11-Jun-17 1:28
JAbedinejad11-Jun-17 1:28 
QuestionLike Pin
Clifford Nelson28-Feb-16 10:41
Clifford Nelson28-Feb-16 10:41 
Questionhow can I assign icon from code? Pin
uTILLIty20-Jan-15 10:10
uTILLIty20-Jan-15 10:10 
QuestionUsing Font Icons Pin
Member 109787544-Nov-14 6:39
Member 109787544-Nov-14 6:39 
AnswerRe: Using Font Icons Pin
michael432119-Dec-14 14:42
michael432119-Dec-14 14:42 
QuestionExtensible for hover trigger/event? Pin
Member 874244212-Dec-13 11:13
Member 874244212-Dec-13 11:13 
GeneralMy vote of 5 Pin
ketan italiya12-Aug-13 21:45
ketan italiya12-Aug-13 21:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.