Some time ago I needed to display some text in my WPF application using a custom font. As a custom font I see a font that is not installed in Fonts folder in your (or the clients of your application) Operating System by default.
It may seem that this is fairly easy task that should be done without any problems in the way. After all, adding a custom font to your application is very similar to adding some image. And because displaying an image is not a big deal I was hoping that displaying a Label or TextBlock with custom font will also be relatively easy. But as I am going to show you, it is not. Tutorials and howto`s on the web take only the simplest scenario under consideration. A scenario that you will probably never see in a business application (all files being put into one folder). In this article I will present solution to this common scenario.
In the provided example I will use font downloaded from this site: http://www.1001freefonts.com/. Also, I would like to give the credit to Saraf uddin Talukder who helped me in solving this issue.
CUSTOM IMAGE VS. CUSTOM FONT
As MSDN`s tutorials and good-practices state, if you intend to use some custom image in your application, you must first add it to your project and then ensure that ‘Build Action’ property is set to Resource:
This will result in your image being compiled into the assembly which is pretty useful since there will be no separate file representing your image in your output directory. Therefore users of your application will find it impossible to change or download your graphics.
Exactly the same rules go for using a custom Font. So you should put it somewhere in your project directory, add it to the project using Solution Explorer and set it Build Action appropriately:
Let’s get back to our Image. To display your image using the standard Image control it is enough to write:
<Image Source="/WpfApplication10;component/Folder1/Water lilies.jpg" />
It is the most comfortable practice to generate this strangely-looking path with your Visual Studio designer.
This is the point where custom image usage differs completely from custom font usage. MSDN  offers you two basic ways for applying font for a Label control (I shall be using label control in this article but the principles works as well for other similar controls like a TextBlock):
<TextBlock FontFamily="file:///d:/MyFonts/#Pericles Light">
Which is pretty useless since it uses absolute location – so it’s not a very flexible solution. Two developers working in one project may have the project files in two different location – in that case it wouldn’t work. Second possibility is:
<TextBlock FontFamily="./resources/#Pericles Light">
Which looks much better. When I saw at first I thought that this is just a simple way of referencing the font with an relative path. I thought that the dot ‘.’ points to the root of my project directory – just as always. So, if my project structure looks like this:
and I would like to use my Katana font in Window2, I should write:
Which surprisingly doesn`t work at all.
As it turned out the little dot ‘.’ points not to the root of my project directory but to the exact location of a Window or Control where it is used. So, in order to use this font I should write:
Two dots ‘..’ of course mean that you want to go one step up in folders tree. But if such, this solution is also rather useless since it is not flexible at all. If you will change location of your Window where such font is used, then it will stop working. What’s more, it will stop working silently. You will not get any error, not even a warning. All elements that used that font before will now switch to use a default font. This is really not a nice behavior. What I really want is the way to set the path to my font relatively from the root of my application.
Fortunately it Is possible. It involves using even more wicked string than before but works as expected:
Three notes at the end:
- ‘Katana’ is the name of the font, not the name of the file. This is significant difference. To get the name of the font simply click the file twice.
- Remember to put the hash sign ‘#’ in front of font name. It will not work otherwise.
- Custom font may also be added to the project with ‘Build Action’ set to ‘Content’. This is not recommended approach however and for the sake of simplicity I ignored this possibility.
Applying custom font to WPF application is certainly more complex and strange than it should be. There are a couple of articles in the Web that show how to deal with this issue but they all concern only about the simplest scenario – when all files are being put into one folder. In business application you are likely to have more complex folders tree – e.g. user controls put into one location, windows into another, and also another for resources like fonts. This is the most common scenario which is also the most poorly documented as well. I hope this article will help you in such situation.