How to include external font in WPF application without installing it
I use such XAML code:
<Style x:Key="Hatten">
<Setter Property="TextElement.FontFamily" Value="Resources/#HATTEN" />
</Style>
#HATTEN - reference to hatten.tft in Resources.
Using the Style:
<TextBlock x:Name="lblTitle" Style="{DynamicResource Hatten}" FontSize="72"></TextBlock>
Include Fonts in WPF Application
Embedding fonts in WPF as resources, is pretty simple. However, there are few gotchas that you need to be aware of.
Here is a step by step process that I followed in a sample app:
Added Resources
/Fonts
folders to my project
Dragged the Source Sans Pro .ttf
files into the Fonts
folder
Visual Studio automatically set their Build Action
to Resource
Note: You don't need to copy them to the output directory if they are being used as resources
Created a Fonts.xaml
ResourceDictionary
with the following code
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FontFamily x:Key="Regular">pack://application:,,,/WpfApp4;component/Resources/Fonts/#Source Sans Pro</FontFamily>
<FontFamily x:Key="Black">pack://application:,,,/WpfApp4;component/Resources/Fonts/#Source Sans Pro Black</FontFamily>
</ResourceDictionary>
Then I merged in the Fonts.xaml
resources into my App.xaml
file.
<Application x:Class="WpfApp4.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Fonts.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
The first problem you have is an incorrect Pack Uri format.
pack://application:,,,/YourAppNamespace;component/Resources/Fonts/#Font Family Name
The second problem you have is an incorrect font family name
The font family name is usually not the same as the .ttf file name!
To get the right family name, I highly recommend using the dp4 Font Viewer.
I hope this helps!
How to add custom fonts in Visual Studio and show fonts in the properties menus?
- Add the (external) font to the solution. You can add it as a resource too which is the best practice.
- Close the XAML and associated files.
- Reopen the file and go to properties and you will see the added font
- If not close the solution and do the above. You should see the font
If it doesn't work for any reason you can specify the relative path of the font as shown in the image:
Also, check How to include external font in WPF application without installing it for other best practices which include using Style
Using a custom font in WPF
I tried your code with this
<Setter Property="TextElement.FontFamily" Value="fonts/#Arial Narrow Bold"/>
and it worked successfully.
Have you marked your font as 'Resource' in the Build Action? If you haven't, do that now and try your code again.
How to load external font file in WPF on runtime
Unfortunately it's not possible to directly reference the font file path. You need two things: The directory where the font file exists and the font name.
So in your case you can set the font family using the following code:
btn.FontFamily = new FontFamily("file:///d:/Fonts/#Ashley");
For reference see chapter Specifying Fonts in Alternate Directories in the MSDN document "FontFamily Class".
WPF load font from Resources
There's a memory leak you need to be aware of.
Any font reference which uses a relative path will cause a memory leak.
The way to do this is to use an absolute path.
And yes, that is a nuisance.
See this:
WPF TextBlock memory leak when using Font
I've recently been working on something which uses fancy fonts and investigated the issue. It's still there with .net 4.7.
I wouldn't use a temporary folder, deliver your ttf to the same folder as your exe or into local appdata if you have several apps which will use the same ttf.
My plan, when I get round to this specific aspect of our app, is to write a custom markup extension which will allow me to pass a short name and go find the absolute path on the user's machine. I'll be using appdata.
Your immediate problem is because you're not using a relative path. Put a / in front of your path there.
Value="/Resources/#Abstract"
But you will then have a memory leak.
Related Topics
Export to Excel from a List with Epplus
Preprocessor Directives in Razor
Does Anyone Still Use [Goto] in C# and If So Why
How to Convert String to Double with Proper Cultureinfo
Transparency for Windows Forms Textbox
Which Is Better, Return Value or Out Parameter
C#:What If a Static Method Is Called from Multiple Threads
How to Call a Non-Static Method from a Static Method in C#
Xml.Loaddata - Data at the Root Level Is Invalid. Line 1, Position 1
Must Declare Scalar Variable @Id
Why Is .Contains Slow? Most Efficient Way to Get Multiple Entities by Primary Key
Reading Excel File Using Oledb Data Provider
Get the Value for a Listbox Item by Index
How to Use Mvvmlight Simpleioc
How to Loop Through Ienumerable in Batches
How to Get Command Line Arguments of Other Processes from .Net/C#