XAML - 使用来自另一个程序集的资源字典的字体

XAML - Using fonts from resource dictionary from another assembly

我正在构建一个使用来自另一个程序集的 ResourceDictionaries 的应用程序,但我在使用字体时遇到了问题。

有一个名为 MyFontAssembly 的程序集,它存储字体以及对它们的引用作为 ResourceDictionary。它的结构如下:

MyFontAssembly
    - FontDictionary.xaml - (stores references to fonts)
    - Fonts
        - FontA.ttf
        - FontB.ttf
          ...

还有另一个组件存储 ResourceDictionaries 用于样式控件,它称为 MyStylesAssembly。来自 MyStylesAssembly 的 ResourceDictionaries 然后合并到应用程序的 App.xaml 中,以提供可重用的样式。

问题是我的样式确实识别字体资源(代码没有崩溃,因为它无法通过它的键找到资源),但是它看起来存储为 ttf 文件的字体未应用。

我在 FontDictionary.xaml 中尝试了以下方法,但 none 有效:

<FontFamily x:Key="MyFontKey">Fonts/#MyFontName</FontFamily>
<FontFamily x:Key="MyFontKey">pack://application:,,,/MyFontAssemblyName;Component/Fonts/#MyFontName</FontFamily>
<FontFamily x:Key="MyFontKey">/MyFontAssemblyName;Component/Fonts/#MyFontName</FontFamily>
<FontFamily x:Key="MyFontKey">pack://application:,,,/Fonts/#MyFontName</FontFamily>

注意:

创建 WPF Class Library.Lets 说 FontLibraryCommon

现在删除App.Xaml和MainWIndow.Xaml如下图

现在将项目属性更改为class库并编译

现在添加字体文件夹及其下的现有 TTF 文件,如图所示。例如我使用 Pacifico 字体

现在在你的库中添加 ResourceDictioanry 让我们说 FontDictioanry.xaml 你的 xaml 应该是这样的

Here is the code

  <ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:FontLibraryCommon">
   <FontFamily x:Key="Pacifico">Fonts/#Pacifico</FontFamily>

 </ResourceDictionary>

现在在你的其他项目中添加字体库作为参考 在你的 MainWindow.Xaml `

<Window.Resources>
    <ResourceDictionary Source="pack://application:,,,/FontLibraryCommon;component/FontDictioanry.xaml"></ResourceDictionary>
</Window.Resources>`

最后一个 Lets Say 标签你可以这样设置

<Label FontFamily="{StaticResource Pacifico}"> Raman</Label>

这是一种从不同库中引用字体的方法。 假设我们有一个名为 MyAwesomeFonts 的库,这里是它的项目结构:

MyAwesomeFontsLibrary
 |
 |__ Fonts\
 |      |
 |      |__ Fonts.cs
 |      |__ MyAwesomeFont.ttf
 |
 |__ Themes\
        |
        |__ generic.xaml

Fonts\ 文件夹中放置字体,在 generic.xaml 文件中声明字体通常如下所示:

xmlns:fonts="clr-namespace:MyAwesomeFontsLibrary.Fonts"...
<FontFamily 
     x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type fonts:Fonts}, ResourceId=MyAwesomeFont}">Fonts/#My Awesome Font Name</FontFamily>

并且在 Fonts.cs 文件中包含:

// say this class declared in namespace: MyAwesomeLibrary.Fonts
public class Fonts
{
    public static ComponentResourceKey MyAwesomeFontKey => new ComponentResourceKey(typeof(Fonts), "MyAwesomeFont");
}

对于您拥有的每种字体,您都执行与上面相同的操作,将它们添加到 Fonts 文件夹,在 generic.xaml 文件中将它们声明为资源,最后创建一个静态文件属性 在 Fonts.cs

现在构建你的库,在你想要使用它的项目中添加对它的引用,并将你的 AwesomeFontsLibrary 的命名空间添加到你的 XAML 类似的东西:

<... xmlns:fonts="clr-namespace:MyAwesomeFontsLibrary.Fonts;assembly=MyAwesomeFontsLibrary" >

下面是在 TextBlockstyle 中重用 AwesomeFontsLibrary 字体的两个片段:

风格:

<Style x:Key="MyTextBlockStyle"
           TargetType="TextBlock">
        <Setter Property="FontFamily" Value="{DynamicResource {x:Static fonts:Fonts.MyAwesomeFontKey}}"></Setter>
    </Style>

或直接在文本块中:

    <TextBlock FontFamily="{DynamicResource {x:Static fonts:Fonts.MyAwesomeFontKey}}" FontSize="50">Welcome!</TextBlock>

You must use Dynamic Resource, not static resource, when using a ComponentResourceKey

Your new font my not appear in designer window but in runtime it will work.

以上步骤已在我的机器上进行测试并且有效。希望这会有所帮助。

找到答案here。我必须将 build action 设置为 resource,然后使用以下方式引用它们:

<FontFamily x:Key="MyFontKey">pack://application:,,,/MyFontAssemblyName;Component/Fonts/#MyFontName</FontFamily>

或更短的版本:

<FontFamily x:Key="MyFontKey">/MyFontAssemblyName;Component/Fonts/#MyFontName</FontFamily>