81

How to include external font in WPF application without installing it

I tried this code

  System.Drawing.Text.PrivateFontCollection privateFonts = new    System.Drawing.Text.PrivateFontCollection();
  privateFonts.AddFontFile("C:\\Documents and Settings\\somefont.ttf");
  System.Drawing.Font font = new Font(privateFonts.Families[0], 12);
  this.label1.Font = font;

It working correctly in Windows Form Application but not in WPF.

Shebin
  • 3,310
  • 2
  • 24
  • 27

13 Answers13

195

There are two ways of doing this: One way is to package the fonts inside the application. The other way is to have the fonts in a folder. The difference is mostly the URI you need to load the files with.

Package with Application

  1. Add a /Fonts folder to your solution.

  2. Add the True Type Fonts (*.ttf) files to that folder

  3. Include the files to the project

  4. Select the fonts and add them to the solution

  5. Set BuildAction: Resource and Copy To Output Directory: Do not copy. Your .csproj file should now have a section like this one:

      <ItemGroup>
       <Resource Include="Fonts\NotoSans-Bold.ttf" />
       <Resource Include="Fonts\NotoSans-BoldItalic.ttf" />
       <Resource Include="Fonts\NotoSans-Italic.ttf" />
       <Resource Include="Fonts\NotoSans-Regular.ttf" />
       <Resource Include="Fonts\NotoSansSymbols-Regular.ttf" />
     </ItemGroup>
    
  6. In App.xaml add <FontFamily> resources. It should look like in the following code sample. Note that the URI doesn't contain the filename when packing with the application.

     <Applicaton ...>
     <Application.Resources>
         <FontFamily x:Key="NotoSans">pack://application:,,,/Fonts/#Noto Sans</FontFamily>
         <FontFamily x:Key="NotoSansSymbols">pack://application:,,,/Fonts/#Noto Sans Symbols</FontFamily>
     </Application.Resources>
     </Application>
    
  7. Apply your fonts like this:

     <TextBlock x:Name="myTextBlock" Text="foobar" FontFamily="{StaticResource NotoSans}" 
                FontSize="10.0" FontStyle="Normal" FontWeight="Regular" />
    
  8. You can also set the font imperatively:

     myTextBlock.FontFamily = new FontFamily(new Uri("pack://application:,,,/"), "./Fonts/#Noto Sans");
    

Copy to Output Directory

  1. Add a /Fonts folder to your solution.

  2. Add the True Type Fonts (*.ttf) files to that order

  3. Include the files to the project

  4. Select the fonts and add them to the solution

  5. Set BuildAction: Content and Copy To Output Directory: Copy if newer or Copy always. Your .csproj file should now have a section like this one:

      <ItemGroup>
       <Content Include="Fonts\NotoSans-Bold.ttf">
         <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       </Content>
       <Content Include="Fonts\NotoSans-BoldItalic.ttf">
         <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       </Content>
       <Content Include="Fonts\NotoSans-Italic.ttf">
         <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       </Content>
       <Content Include="Fonts\NotoSans-Regular.ttf">
         <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       </Content>
       <Content Include="Fonts\NotoSansSymbols-Regular.ttf">
         <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       </Content>
     </ItemGroup>
    
  6. In App.xaml add <FontFamily> resources. It should look like in the following code sample.

     <Applicaton ...>
     <Application.Resources>
         <FontFamily x:Key="NotoSansRegular">./Fonts/NotoSans-Regular.ttf#Noto Sans</FontFamily>
         <FontFamily x:Key="NotoSansItalic">./Fonts/NotoSans-Italic.ttf#Noto Sans</FontFamily>
         <FontFamily x:Key="NotoSansBold">./Fonts/NotoSans-Bold.ttf#Noto Sans</FontFamily>
         <FontFamily x:Key="NotoSansBoldItalic">./Fonts/NotoSans-BoldItalic.ttf#Noto Sans</FontFamily>
         <FontFamily x:Key="NotoSansSymbols">./Fonts/NotoSans-Regular.ttf#Noto Sans Symbols</FontFamily>
     </Application.Resources>
     </Application>
    
  7. Apply your fonts like this:

     <TextBlock Text="foobar" FontFamily="{StaticResource NotoSansRegular}" 
                FontSize="10.0" FontStyle="Normal" FontWeight="Regular" />
    

References

janw
  • 8,758
  • 11
  • 40
  • 62
MovGP0
  • 7,267
  • 3
  • 49
  • 42
  • 9
    Please clarify where `#names` are coming from and how they are constructed. Just file name without extensions preceded by `#`? Otherwise: great, detailed answer! – Jack Miller Dec 15 '16 at 12:04
  • 2
    the string after the hash is the name of the font. unfortunately i don't really know how to get them except opening the font file in preview or installing it and using the font selection in an text editor. there might be a better way of doing this... – MovGP0 Dec 16 '16 at 00:32
  • 1
    The package option does not work for me in VS2017. I followed your instructions to the letter. – Kyle Delaney Apr 15 '17 at 23:47
  • 1
    Step "6" in "Package with Application" works in VS2015, but... at runtime application shows just empty squares! I removed "FontFamily" resource and specified font directly in style's Setter: `` – Vincent Jul 10 '17 at 12:49
  • 1
    @KyleDelaney I followed the steps in "Package with Application" in VS2017 but it didnt work. But after I changed `build action` to `Content` and `Copy to Output Directory` to `Copy if newer`, it works fantastically. – NearHuscarl May 24 '18 at 07:18
  • 1
    This suffers from the WPF memory leak issue as detailed in https://stackoverflow.com/questions/31452443/wpf-textblock-memory-leak-when-using-font as do all the other solutions given here it seems. – nietras Jun 21 '18 at 08:51
  • I tried doing this with `AddFontMemResourceEx` but seem to have issues with as can be seen in https://stackoverflow.com/questions/50964801/wpf-use-font-installed-with-addfontmemresourceex-for-process-only – nietras Jun 21 '18 at 09:32
  • 3
    @JackMiller, I know it's been a while, but I had the same question. You can get the `#names` by doing the following: Right-click the font in Windows explorer. Go to Properties -> Details -> Title. – Rachel Martin Nov 12 '18 at 19:40
  • 1
    Does the memory leak still occur when using the second method of copying to the output directory? – ataraxia Feb 15 '19 at 10:31
  • 17
    FYI that cryptic `#NotoSans` identifier is not driven by the file name. You need to double click on the file in Windows which opens the preview window for the font. There will be a label that says "Font name: NotoSans", it's that font name you want to use when referencing in WPF. – The Muffin Man Jun 05 '19 at 17:03
  • in VS2019 and dotnet core 3 I used ```/MyResourceClassLib;component/Fonts/#Font Awesome 5 Free Solid``` in step 6 – JvdBerg Jun 15 '19 at 17:24
  • Thank you so much for this explanation! – Kamil Jul 01 '19 at 21:54
  • 1
    There is an error: ./Fonts/NotoSans-Regular.tts should be: ./Fonts/NotoSans-Regular.ttf – Rye bread May 04 '21 at 15:02
  • @Rugbrød Thanks. I've fixed that in the code sample. – MovGP0 May 07 '21 at 14:27
33

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>
Pavlo Hermanov
  • 472
  • 5
  • 8
  • 8
    The code snippet ` – Jack Miller Dec 15 '16 at 12:02
  • 1
    @KyleDelaney In VS2017 you can just add a Fonts folder to your source as Resources and you can then choose the font with the drop-down menu box, looking something like this: `FontFamily="/AppName;component/Fonts/#Font Name"` – kayleeFrye_onDeck May 14 '19 at 01:17
  • This isn't an answer to the question right? None of the answers here explains how to include EXTERNAL fonts in the project. Does that simply mean, that it's not possible to load a font dynamically during runtime into the project? – TobiasW Dec 23 '20 at 09:03
23

The best answer to this question I found here

http://geekswithblogs.net/Martinez/archive/2010/01/29/custom-font-in-wpf-application.aspx

SOLUTION It involves using even more wicked string than before but works as expected:

<Label FontFamily="pack://application:,,,/Folder1/#Katana Sans">Text</Label> 

Where is Folder1 is a folder of your project where you keep a TTF file. Three notes at the end:

  1. ‘Katana Sans’ 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. Note that spaces are included without any changes in this string.

  2. Remember to put the hash sign ‘#’ in front of font name. It will not work otherwise.

  3. 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.

Some extra links

https://msdn.microsoft.com/en-us/library/ms753303(v=vs.100).aspx

https://msdn.microsoft.com/en-us/library/cc296385.aspx

Jonathan Tuzman
  • 11,568
  • 18
  • 69
  • 129
NoWar
  • 36,338
  • 80
  • 323
  • 498
  • Can you pick a font file and use it? – lindexi Jun 28 '17 at 08:39
  • 1
    Important: "‘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." – Gabe Halsmer Apr 26 '18 at 00:37
  • How does it know what the filename is though? Surely the file name needs to go somewhere? This solution doesn't work for me. – rollsch Aug 16 '19 at 09:08
  • 1
    @rolls It will look through the folder for font files and pick the one that matches that name. – Cole Tobin Dec 16 '19 at 21:59
  • What made the difference for me was including spaces! My `Nunito Sans` is used as `#Nunito Sans` not `#NunitoSans` or `#Nunito_Sans` or anything else! – Jonathan Tuzman Jul 10 '20 at 21:57
12

The easiest way to include external fonts is to

Step 1. Create the folder Fonts And add your fonts into it.

enter image description here

Step 2. Set Build action to content and Copy to Output Directory to Copy always.

enter image description here

Step 3. Build the Solution to update it with the Font directory.

Step 4. Use the font in your elements using FontFamily="Fonts/#font name"

enter image description here

All Done!

Thanks to cscience !

Saghachi
  • 851
  • 11
  • 19
10

I did not found any answer for exactly that. But I found a solution that I did not saw on Internet.

I followed a recommendation of doing a folder and marking all the files inside as Resources. But I needed to enumerate them, and that was my main problem, because I need to load all to my screen without recording the name somewhere. I just want to simple drop another font to that folder and list it.

I found this as a solution to list all the files inside my resources/fonts folder

Fonts.GetFontFamilies(new Uri("pack://application:,,,/resources/fonts/#"))

I expect it to help you organize your fonts.

4

I use xaml for this

<Window

 FontFamily ="./Fonts/#somefont"

>

I included the font file inside the "Fonts" folder

Tharindu
  • 91
  • 4
4

First) Copy fonts to project folder like /Resources/Fonts/ and set font-properties -> Build Action:Resource

Second) Used on code

FontFamily="/AssemblyNamespace;component/Resources/Fonts/IranSans/#IRANSansWeb Medium"

enter image description here

Moslem Shahsavan
  • 1,211
  • 17
  • 19
  • 1
    Your solution for setting the font properties to Build Action: Resource solve it for me. Only you need this in pack://application:,,,/AssemlyName;component/Resources/Fonts/#IRANSansWeb – Mour_Ka Jun 22 '20 at 09:53
3

Here's What Worked for me:

(1) Add Directory to project: font

(2) Move ttf font file into font directory

(3) Add ttf font file to project

(4) Set the "Build" Property of the tff font file to "Resource" (Note: I used "Resource" instead of "Embedded Resource" in the combobox selection.)

(5) Open the Window where you are using the font and make the following changes:

<Window ... >
    <Window.Resources>
        <FontFamily x:Key="YourFontNickName">
        pack://application:,,,/font/#NameOfFont
        <!-- Note: NameOfFont can be font by double clicking
             on font from explorer and writing down name
             of the font reported.  Its not the same
             as the file name -->
        </FontFamily>   
    </Window.Resources>


    <!-- Use font as Xaml -->
    <StackPanel>
        <Textblock FontFamily="{StaticResource YourFontNickName}">
        This is a test
        </Testblock>
        <Textblock Name="text1"/>
    </StackPanel>
...
</Window>

(6) If you want to change the font from code. Do this:

public partial class Window1 : Window {

    // Use font as C# Code
    public void UpdateText1() {

            text1.Text      = "Hi There";
            FontFamily ff   = this.Resources["YourFontNickName"] 
                                as FontFamily;
            if (ff == null) {
                Messagebox.Show("Wrong Font Name", "ERROR");
                return;
            }
            text1.FontFamily = ff;
            text1.FontSize   = 30;
    }

    ...
}
Bimo
  • 5,987
  • 2
  • 39
  • 61
3

Although the solution from @movgp0 worked at first, it failed when I wanted a Bold text. By searching a bit more online I found the following solution that works in all cases:

<Application.Resources>
  <FontFamily x:Key="FiraSansBold">Fonts/FiraSansCondensed-Bold.ttf#Fira Sans Condensed</FontFamily>
  <FontFamily x:Key="FiraSansBoldItalic">Fonts/FiraSansCondensed-BoldItalic.ttf#Fira Sans Condensed</FontFamily>
  <FontFamily x:Key="FiraSansItalic">Fonts/FiraSansCondensed-Italic.ttf#Fira Sans Condensed</FontFamily>
  <FontFamily x:Key="FiraSans">Fonts/FiraSansCondensed-Regular.ttf#Fira Sans Condensed</FontFamily>
</Application.Resources>

Usage: <Label FontFamily="{StaticResource FiraSansBold}">SomeBoldedLabel</Label>

nrod
  • 398
  • 6
  • 17
2

I have a fonts folder inside an assets folder in my project. At build time it will copy those fonts into the folder as content. Then I can simply use the following XAML to use the FontAwesome font to have an icon on my button.

<Button Content="&#xf0c9;" FontFamily="./assets/fonts/#FontAwesome">
Steve Parish
  • 1,824
  • 2
  • 14
  • 12
2

You need to add fonts as resource item

according to the link; you may add your desired font as application resource file by following these steps:

  1. copy your font file to anywhere in your project in most cases resource files is copied into a folder named "resources" if you want to follow this, create new folder in your project and name it as "resources" then copy your font file which is usually have ttf or otf format into that folder

  2. then you need to declare this file as a resource file for doing so you have two options:

    1. right click on your font file, select properties (or press F4 after selecting it) and then change "Build Action" to "Resource"
    2. go into your projects directory edit project-name.csproj file and the following tag:

      <ItemGroup>            
          <Resource Include="resources\<font-file-name>.ttf" />  
      </ItemGroup>```
      

finally within you application you may set font-family property like this:

FontFamily="./Resources/Fonts/#<font-name>"

be careful 'font-name' is different from font-file-name you may open font file and check for font name property (in Microsoft Window)

fetching font name by opening font file

DAkbariSE
  • 151
  • 1
  • 13
0

I was trying to get this to work as well with a different font, it only worked for me in this format with the ./Fonts

<FontFamily x:Key="NotoSans">pack://application:,,,./Fonts/#Noto Sans</FontFamily>

0

Kind of, Really easy:

<TextBlock x:Name="lblTitle" FontSize="24" Margin="256,25,178,289" Text="gg" FontFamily="/FontTest;component/#Arvo"></TextBlock>

When you import a font, vs will gonna include it in font list.

Dude4
  • 163
  • 1
  • 8