Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

Creating an IconBlock in Xaml

0.00/5 (No votes)
11 Jun 2015CPOL2 min read 10.6K  
Create an easily resusable IconBlock (TextBlock that display's an icon)

Introduction

Have you ever tried to display an icon but you have to search for the icon code that you want? Or having a Textblock that has a the icon code hard coded in the text property of a textblock and you can't remember what kind of icon it is? It's either you google it, look it up in the character map or just run your code to see it display.

This is a sample custom control that allows you to display an icon easily.

Background

Segoe UI Symbol is a font that we can use to display icons. To display icons in a xaml Text block we set the Text attribute to the icon code.

In order to display a SegoeUI symbol you need to:

XAML
<StackPanel Orientation="Horizontal">
    <TextBlock Text="&#xe171;" FontFamily="Segoe UI Symbol"/><TextBlock Text="Some Text" />
</StackPanel>

With this approach, it's hard to remember what kind of icon is "&#xe171;" .

You can also use the SymbolIcon tag to display an icon but you're limited to what is defined in the SymbolEnum.

<SymbolIcon Symbol="enumMemberName"/>

Using the code

In this code we have the custom control, an enum that has the icon codes we want to display and the default style for the custom control.

The custom control has dependency properties IconProperty and IconTextProperty. the IconProperty's type will be an IconEnum. This will help us get an intellisense on the xaml editor. Every time the IconProperty is updated we change the IconTextProperty which is Template-bound to the TextBox for the icon (look at the ContentTemplate in the default style).

C++
public class IconBlock : Control
{
    public static readonly DependencyProperty IconProperty =
      DependencyProperty.Register("Icon",
          typeof(IconEnum),
          typeof(IconBlock),
          new PropertyMetadata(null, IconChanged));

    public IconEnum Icon
    {
        get { return (IconEnum)GetValue(IconProperty); }
        set { SetValue(IconProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
      DependencyProperty.Register("Text",
          typeof(string),
          typeof(IconBlock),
          new PropertyMetadata(null));

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty IconTextProperty =
        DependencyProperty.Register("IconText",
        typeof(string),
        typeof(IconBlock),
        new PropertyMetadata(null, IconChanged));

    public string IconText
    {
        get { return (string)GetValue(IconTextProperty); }
        set { SetValue(IconTextProperty, value); }
    }

    private static void IconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var instance = d as IconBlock;
        if (instance != null)
        {
            int intIcon = (int)instance.Icon;
            instance.IconText = Char.ConvertFromUtf32(intIcon);
        }
    }
}

This is the enum for the Icons. We put here every icon that we want to use and put a name on it. this will make it easier for us to remember the icon and give us intellisense in the xaml editor. Here are just some icons, you can freely add more icons as you want. You can get some icon codes from the character map app in windows or you can check this page.

C++
public enum IconEnum
{
    InTransit = 0x1f690,
    X = 0xe10a,
    Exclamation = 0xe171,
    ActionClose = 0x1f4ea,
    Mailbox = 0x1f4ea,
    MailboxNewMail = 0x1f4eb,
    Play = 0xe213,
    Stop = 0xe25e,
    Gift = 0x1f381
}

This is the default style for the IconBlock. I have in the ContentTemplate two TextBlocks. The first text block displays the icon and the second on displays a regular text next to the icon.

C++
<Style TargetType="local:IconBlock">
      <Style.Setters>
          <Setter Property="Template">
              <Setter.Value>
                  <ControlTemplate TargetType="local:IconBlock">
                      <StackPanel Orientation="Horizontal">
                          <Grid Margin="5,-5,5,0">
                              <TextBlock Text="{TemplateBinding IconText}"
                                     FontFamily="Segoe UI Symbol"/>
                          </Grid>
                          <TextBlock Text="{TemplateBinding Text}"
                                     />
                      </StackPanel>
                  </ControlTemplate>
              </Setter.Value>
          </Setter>
      </Style.Setters>
 </Style>

To use the custom control you simply just add the tag to your xaml. No need to remember those icon codes everytime you create an IconBlock.

C++
<local:IconBlock Icon="ActionClose" Text="This is a close icon." FontSize="20"/>

Conclusion

There are already some ways on how to display an icon in XAML. With this code, you can have your own enum of icons and you can also make your code simpler by having the text and the icon in just one tag.

I have tested this both in WPF and in WinRT. I hope this little code helped you in your development.

License

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