15
votes

I have an application that uses a separate library assembly for resources (but not a resource-only assembly with no code), and I would like to include a custom font in the library.

I am able to get the font, which is an Open Type Font, to load if I add its .otf file as a resource to the project for the executing assembly (rather than to the resource library project), with properties set as Build Action = 'Resource' and Copy to Output = 'Do Not Copy', by using the following code:

FontFamily font = new FontFamily(new Uri("pack://application:,,,/"), 
                      "./Resources/#CustomFont")); // Resources is a subfolder

When I try to add the font to the resource library project, however, the font does not load. I tried using the following code to load it (also of note: I do not have much experience with pack URIs):

FontFamily font = new FontFamily(new Uri("pack://application:,,,/MyLibrary"),
                      "./Resources/#CustomFont")); 
                      // there is a Resources subfolder in my library as well
                      // not sure about whether I need the .

The library does work for other resources, such as images.

I've also tried a bunch of other permutations for the URI with no success (it also does not throw exceptions, just displays with the default font, not sure if this is a separate issue).

I've been working from Packaging Fonts with Applications on MSDN, which has an example of creating a font resource library, but no examples using code behind (I am forced to use code behind for this).

Any ideas about what I need to do? Am I off track?

4

4 Answers

21
votes

I have it working in my application (loading fonts from another assembly in code-behind). For a font URI like this:

pack://application:,,,/MyAssembly.Name;component/Resources/Fonts/#Swis721 Md BT

The way I got it to work (after painful trial and error, if I remember correctly) is:

new FontFamily(
    new Uri("pack://application:,,,/MyAssembly.Name;component/Resources/Fonts/"),
    "./#Swis721 Md BT"
)

Hope that helps.

1
votes

WPF does not support creating the FontFamily object programmatically using pack notation.

The docs say it in the end of the page, here

Here is the quote:

Absolute URI using the pack: notation: WPF applications do not allow you to create a FontFamily object programmatically using "pack:" as part of the absolute uniform resource identifier (URI) reference to a font. For example, "pack://application:,,,/resources/#Pericles Light" is an invalid font reference.

0
votes

(I know, old question, but I didn't find a correct answer.)

the Ross's answer only works in some versions of the netframework . (Does not work on netframework 4.6)

I think this is the best answer :

Enumerating Fonts in an Application :

 foreach (FontFamily fontFamily in Fonts.GetFontFamilies(new Uri("pack://application:,,,/"), "./resources/"))
            {
                // Perform action.
            }

reference

0
votes

In order to reference font resource items from code, you must supply a two-part font resource reference: the base uniform resource identifier (URI); and the font location reference. These values are used as the parameters for the FontFamily method. The following code example shows how to reference the application's font resources in the project subdirectory called resources.

// The font resource reference includes the base URI reference (application directory level),
// and a relative URI reference.

myTextBlock.FontFamily = new FontFamily(new Uri("pack://application:,,,/"), "./resources/#Pericles Light");

The base uniform resource identifier (URI) can include the application subdirectory where the font resource resides. In this case, the font location reference would not need to specify a directory, but would have to include a leading "./", which indicates the font resource is in the same directory specified by the base uniform resource identifier (URI). The following code example shows an alternate way of referencing the font resource item—it is equivalent to the previous code example.

// The base URI reference can include an application subdirectory.

myTextBlock.FontFamily = new FontFamily(new Uri("pack://application:,,,/resources/"), "./#Pericles Light");

Source: docs.microsoft.com