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

时间:2017-10-06 08:45:12

标签: wpf xaml fonts resourcedictionary mergeddictionaries

我正在构建一个使用来自其他程序集的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项目中使用<FontFamily x:Key="MyFontKey">Fonts/#MyFontName</FontFamily>实现具有相同的结构,一切都很好,当我将实现分成几个程序集时,问题出现了,就像我在重构期间所描述的那样。
  • MyFontAssembly已正确合并到MyStylesAssembly。我只是在这里用它来称呼它,在实际代码中它还有一些ResourceDictionariesMyStylesAssembly正确使用。问题似乎是只有<FontFamily>标签无法识别ttf文件。
  • MyFontAssemblyMyStylesAssembly是tyle ClassLibrary的项目,不包含ResourceDictionaries以外的任何代码(没有后面的类或代码)

3 个答案:

答案 0 :(得分:3)

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

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

或更短的版本:

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

答案 1 :(得分:1)

创建一个WPF类库。让我们说FontLibraryCommon enter image description here

现在删除App.Xaml和MainWIndow.Xaml,如下所示 enter image description here

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

enter image description here

现在在其下添加字体文件夹和现有的TTF文件,如图所示。我使用Pacifico字体作为示例 enter image description here enter image description here

现在添加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>

答案 2 :(得分:1)

这是从传送库引用字体的一种方法。 假设我们有名为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文件中创建静态属性1}}

现在构建你的库,在你想要使用它的项目中添加对它的引用,并将你的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中:

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

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

     

你的新字体我没有出现在设计师窗口中,但在运行时它会起作用。

以上步骤在我的机器上进行测试,然后才能正常运行。希望这会有所帮助。