Change the Default Font of a WPF Application


Introduction

When you create a new application in WPF all text will be displayed using the default font of your operating system. If you’re running Vista the default font will be ‘Segoe UI’, if you’re running on XP I expect it will be Tahoma.

WPFDefaultFontBefore 

Where does the Default Font come from?

There are two main controls which display text in WPF; the TextElement and TextBlock. Both of these controls have a FontFamily property which is backed by a FontFamilyProperty DependencyProperty. We’ll start by looking at the FontFamilyProperty on the TextElement class and how that gets it’s default value.

public static readonly DependencyProperty FontFamilyProperty =
	DependencyProperty.RegisterAttached(
		"FontFamily",
		typeof(FontFamily),
		typeof(TextElement),
		new FrameworkPropertyMetadata(
			SystemFonts.MessageFontFamily,
			... Lots of options ...
		new ValidateValueCallback(IsValidFontFamily));

The default value of a DependencyProperty is taken from the Property Metadata supplied when it is registered. In this case the TextElement is being given the default value of SystemFonts.MessageFontFamily which I assume WPF is reading from the host operating system.

The TextBlock is slightly different, it uses the FontFamily property for the same purpose as the TextElement so instead of declaring a new DependencyProperty it just reuses the existing one from the TextElement.

public static readonly DependencyProperty FontFamilyProperty =
	TextElement.FontFamilyProperty.AddOwner(typeof(TextBlock));

This essentially copies the DependencyProperty which was registered on the TextElement and takes the defaults as well as it’s other associated metadata along with it.

Changing the Default Font

The value of a DependencyProperty is determined by a large number of different factors which are evaluated in an order of precedence. At the very bottom is the default value given to the DependencyProperty when it was registered, this is ideally what we would like to change. We are able to specify new PropertyMetadata using the OverrideMetadata method of a DependencyProperty, my first concern with this method is that we would lose the values specified by the framework for the options but this method is clever enough to merge in the new metadata to what was supplied previously. Using the code below we can specify new defaults for the FontFamily of the TextElement and TextBlock controls ensuring that all Text displayed in our application will now use everyone’s favourite font.

TextElement.FontFamilyProperty.OverrideMetadata(
typeof(TextElement),
new FrameworkPropertyMetadata(
    new FontFamily("Comic Sans MS")));

TextBlock.FontFamilyProperty.OverrideMetadata(
typeof(TextBlock),
new FrameworkPropertyMetadata(
    new FontFamily("Comic Sans MS")));

WPFDefaultFontAfter

Limitations of this Technique

In the above image you’ll see that we’ve successfully change the font on the text blocks, labels and buttons. Unfortunately the font inside the TextBox remains unchanged, this is due to it receiving it’s FontFamily property from it’s base class Control. Control adds itself as an Owner of the TextElement FontFamilyProperty but specifies it’s own metadata which we are then unable to override. In this case our only option is to specify a value for the property higher up the DependencyProperty evaluation chain, for example by creating a implicit style for the Control type.

Advertisements

8 thoughts on “Change the Default Font of a WPF Application

  1. Where do I need to put this code?

    I’ve tried putting it in the code-behind of my main window but it has no effect on e.g. labels defined in XAML on that window.

  2. This design is spectacular! You obviously know how to keep a reader amused.
    Between your wit and your videos, I was almost moved to start my own blog (well, almost…HaHa!) Excellent job.
    I really loved what you had to say, and more than that,
    how you presented it. Too cool!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s