How to Use Icon Fonts in WinForms (Windows Forms) Applications

Icon fonts contain symbols instead of numbers and letters. In web technology, icon fonts are dominate compared to other image formats. Since they are vector graphics, users can scale them up and down without losing quality. Also, they are small and easy to load. The only limitation is that a single icon can only be drawn in one color.

The question that often comes to everyone’s mind is, “Can icon fonts be used in WinForms, a desktop application?” Yes, it can. This blog illustrates how.

Remember, in the case of DPI, all we need to do is to change the font size. We don’t have to worry about maintaining images of different sizes for different DPI scaling.

How to add and draw icon fonts

The fonts typically available in a system, like Arial and Times New Roman, may not have the icons we need to use in our applications. There are many online and offline applications that support creating icon fonts. One offline tool, called Metro Studio, is provided free by Syncfusion.

For demonstration, we created a .ttf file that has a font family named “WF Fabric.” The resultant icons are shown in the following figure.

Icon Font - WF Fabric.ttf file

Icon Fonts from WF Fabric.ttf File

Note: The Unicode shown in the previous figure (e700, e701, etc.) represents a respective glyph when being drawn in an application.

Include the WF Fabric.ttf file in your WinForms application and mark its Build Action as Embedded Resource in the properties dialog.WF Fabric.ttf file marked as embedded resource

WF Fabric.ttf File Marked as Embedded Resource

During form initialization, include the code to register icon fonts in the system memory. Like other fonts (Arial, Times New Roman, etc.) WF Fabric will also be registered in the system memory in Control Panel\All Control Panel Items\Fonts.

public Form1()
{
    InitializeComponent();
    this.Paint += Form1_Paint;
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    PrivateFontCollection pfc = new PrivateFontCollection();
    //Extracting icon fonts from the WF Fabric.ttf file and adding into system memory.
    Stream fontAsStream = this.GetType().Assembly.GetManifestResourceStream("WindowsFormsApp1.WF Fabric.ttf");
    byte[] fontAsByte = new byte[fontAsStream.Length];
    fontAsStream.Read(fontAsByte, 0, (int)fontAsStream.Length);
    fontAsStream.Close();
    IntPtr memPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(typeof(byte)) * fontAsByte.Length);
    System.Runtime.InteropServices.Marshal.Copy(fontAsByte, 0, memPointer, fontAsByte.Length);
    pfc.AddMemoryFont(memPointer, fontAsByte.Length);
}

The pfc instance of the PrivateFontCollection class plays a vital role by saving private or custom icon fonts in system memory. The Families property inside the pfc object will hold saved font family names. As mentioned, we created the WF Fabric.ttf with a font family name of WF Fabric.

Now create an enumeration with all the icon fonts with the appropriate name and assign its Unicode with the prefix 0x. So, wherever you draw using the icon font, the Unicode will be converted as a string and passed as a parameter to the DrawString method.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.Paint += Form1_Paint;
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        PrivateFontCollection pfc = new PrivateFontCollection();
        //Extracting icon fonts from the WF Fabric.ttf file and inserting into system memory.
        Stream fontAsStream = this.GetType().Assembly.GetManifestResourceStream("WindowsFormsApp1.WF Fabric.ttf");
        byte[] fontAsByte = new byte[fontAsStream.Length];
        fontAsStream.Read(fontAsByte, 0, (int)fontAsStream.Length);
        fontAsStream.Close();
        IntPtr memPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(typeof(byte)) * fontAsByte.Length);
        System.Runtime.InteropServices.Marshal.Copy(fontAsByte, 0, memPointer, fontAsByte.Length);
        pfc.AddMemoryFont(memPointer, fontAsByte.Length);

        //Icon font's unicode "0xe700" is converted to string and drawn using e.Graphics with WF Fabric set as font family. 
        string iconChar = char.ConvertFromUtf32(IconFont.LastArrow);
        Font iconFont = new Font(pfc.Families[0], 18.5f, FontStyle.Bold);
        e.Graphics.DrawString(iconChar, iconFont, new SolidBrush(Color.Orange), new PointF(10, 10));

        //Icon font's unicode "0xe710" is converted to string and drawn using e.Graphics with WF Fabric set as font family.
        iconChar = char.ConvertFromUtf32(IconFont.Plus);
        e.Graphics.DrawString(iconChar, iconFont, new SolidBrush(Color.Red), new PointF(40, 40));

        //Icon font's unicode "0xe720" is converted to string and drawn using e.Graphics with WF Fabric set as font family.
        iconChar = char.ConvertFromUtf32(IconFont.Paint);
        e.Graphics.DrawString(iconChar, iconFont, new SolidBrush(Color.Green), new PointF(70, 70));
    }
}

public static class IconFont
{
    //0xe700, 0xe710, 0xe720 - are icon font's unicode from the WF Fabric.ttf file.
    public static int LastArrow = 0xe700;
    public static int Plus = 0xe710;
    public static int Paint = 0xe720;
}

Now it’s time to apply icon fonts in a real-world scenario. We have prepared a simple demo that shows navigation icons for first page, last page, previous page, and next page drawn on a custom button control.

Reference sample link: https://github.com/SyncfusionExamples/button-with-font-iconCustom button control with icon font and text drawn inside

Custom button control with icon font and text drawn inside

The advantages of using icon fonts are:

  1. Improved rendering quality in all font sizes.
  2. Reusing a single icon font for different themes and skins by changing color.
  3. Reduction in application size by not having to maintain different image sizes with respect to DPI scaling.
  4. Adding multiple icon fonts as well as concatenating icon fonts with letters, numbers, and symbols.

Thanks for reading. Please post your questions in the comments section.

Tags:

Share this post:

Related Posts

Leave a comment