【问题标题】:XAML - Using fonts from resource dictionary from another assemblyXAML - 使用来自另一个程序集的资源字典中的字体
【发布时间】:2017-10-06 08:45:11
【问题描述】:

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

有一个名为 MyFontAssembly 的程序集将字体连同对它们的引用存储为ResourceDictionary。它的结构如下:

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

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

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

我在FontDictionary.xaml 中尝试了以下方法,但都不起作用:

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

注意:

  • 我确信我的字体格式 ttf 可以正常工作并且命名正确。我在具有相同结构的单个 exe 项目中使用 &lt;FontFamily x:Key="MyFontKey"&gt;Fonts/#MyFontName&lt;/FontFamily&gt; 实现,一切都很好,当我将实现拆分为几个程序集时出现了问题,就像我在重构期间描述的那样。
  • MyFontAssembly 正确合并到 MyStylesAssembly 中。我只是在这里用那个名字来称呼它,在实际代码中,它还有更多ResourceDictionariesMyStylesAssembly 正确使用。问题似乎只是 &lt;FontFamily&gt; 标签无法识别 ttf 文件。
  • MyFontAssemblyMyStylesAssemblyClassLibrary 类型的项目,不包含 ResourceDictionaries 以外的任何代码(没有类或代码)

【问题讨论】:

  • 您是否使用了正确的参考。如果不起作用,您需要参考 XAML URI 包文档约定
  • 我很可能没有使用正确的方法来引用字体,但我不知道正确的方法是什么(这是我的问题,在这里)。
  • 使用示例更新示例

标签: wpf xaml fonts resourcedictionary mergeddictionaries


【解决方案1】:

找到答案here。我必须将build action 设置为resource,然后使用:

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

或更短的版本:

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

【讨论】:

    【解决方案2】:

    创建一个 WPF 类库。让我们说 FontLibraryCommon

    现在删除 App.Xaml 和 MainWINdow.Xaml,如下所示

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

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

    现在在你的库中添加 ResourceDictioanry 比如说 FontDictioanry.xaml 你的 xaml 应该是这样的

    这里是代码

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

    【讨论】:

    • 这几乎就是我在我的应用程序中所做的。 (另外新建项目时还有一个ClassLibrary项目类型,所以不用删除App.xaml和更改输出类型)
    • 那么您面临什么问题?它只在运行时起作用
    【解决方案3】:

    这是从不同库中引用字体的一种方法。 假设我们有一个名为 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 字体的 sn-ps:

    风格:

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

    或者直接在Textblock中:

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

    在使用 ComponentResourceKey 时,您必须使用动态资源,而不是静态资源

    您的新字体不会出现在设计器窗口中,但在运行时会起作用。

    以上步骤已在我的机器上进行了测试,并且可以正常工作。希望这会有所帮助。

    【讨论】:

    • 使用 DynamicResource 代替 StaticResource 可以工作。我没有考虑。无论如何,我在堆栈上的另一个问题上找到了解决我的问题的方法。我必须将我的字体文件构建操作设置为资源并且它可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多