如何在 WPF 应用程序中包含外部字体而不安装它

Posted

技术标签:

【中文标题】如何在 WPF 应用程序中包含外部字体而不安装它【英文标题】:How to include external font in WPF application without installing it 【发布时间】:2011-09-21 04:06:12 【问题描述】:

如何在不安装的情况下在 WPF 应用程序中包含外部字体

我试过这段代码

  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;

它在 Windows 窗体应用程序中正常工作,但在 WPF 中不正常。

【问题讨论】:

【参考方案1】:

我使用这样的 XAML 代码:

<Style x:Key="Hatten">
        <Setter Property="TextElement.FontFamily" Value="Resources/#HATTEN" />
</Style>

#HATTEN - 参考资源中的 hatten.tft。

使用样式:

 <TextBlock x:Name="lblTitle" Style="DynamicResource Hatten" FontSize="72"></TextBlock>

【讨论】:

代码 sn-p &lt;Style&gt; 不完整/具有误导性。最好遵循 MovGP0 的回答。基本相同,但更详细。 OTF 也可以。 @KyleDelaney 在 VS2017 中,您只需将 Fonts 文件夹作为资源添加到源中,然后您可以使用下拉菜单框选择字体,如下所示:FontFamily="/AppName;component/Fonts/#Font Name" 这不是问题的答案,对吧?这里的答案都没有解释如何在项目中包含外部字体。这是否仅仅意味着,在运行时无法将字体动态加载到项目中?【参考方案2】:

我为此使用 xaml

<Window

 FontFamily ="./Fonts/#somefont"

>

我将字体文件包含在“字体”文件夹中

【讨论】:

【参考方案3】:

我没有找到任何答案。 但是我找到了一个我在互联网上没有看到的解决方案。

我遵循了创建文件夹并将其中的所有文件标记为资源的建议。 但是我需要枚举它们,这是我的主要问题,因为我需要将所有内容加载到我的屏幕上,而不需要在某处记录名称。我只想简单地将另一种字体拖放到该文件夹​​并列出它。

我发现这是列出资源/字体文件夹中所有文件的解决方案

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

我希望它能帮助您组织字体。

【讨论】:

请添加指向此 API 参考页面的链接。 GetFontFamilies 可以选择其他文件夹中的字体吗? 这非常有用。【参考方案4】:

我在这里找到了这个问题的最佳答案

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

解决方案 它涉及使用比以前更邪恶的字符串,但按预期工作:

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

Folder1 在哪里是您保存 TTF 文件的项目文件夹。 结尾三注:

    ‘Katana Sans’是字体的名称,而不是文件的名称。这是显着的差异。要获得字体的名称,只需单击文件两次。请注意,在此字符串中包含空格且没有任何更改

    记得在字体名称前加上井号“#”。否则将无法正常工作。

    自定义字体也可以添加到项目中,并将“构建操作”设置为“内容”。然而,这不是推荐的方法,为了简单起见,我忽略了这种可能性。

一些额外的链接

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

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

【讨论】:

你能选择一个字体文件并使用它吗? 重要:“'Katana' 是字体的名称,而不是文件的名称。这是显着的区别。要获得字体的名称,只需单击文件两次。” 它怎么知道文件名是什么?文件名肯定需要去某个地方吗?这个解决方案对我不起作用。 @rolls 它将在文件夹中查找字体文件并选择与该名称匹配的文件。 对我来说与众不同的是包括空格!我的Nunito Sans 用作#Nunito Sans 而不是#NunitoSans#Nunito_Sans 或其他任何东西!【参考方案5】:

我的项目的资产文件夹中有一个字体文件夹。在构建时,它将这些字体作为内容复制到文件夹中。然后我可以简单地使用以下 XAML 来使用 FontAwesome 字体在我的按钮上添加一个图标。

<Button Content="&#xf0c9;" FontFamily="./assets/fonts/#FontAwesome">

【讨论】:

【参考方案6】:

这是执行此操作的两种方法。一种方法是将字体打包在应用程序中。另一种方法是将字体放在文件夹中。区别主要在于加载文件所需的 URI。

应用程序包

    /Fonts 文件夹添加到您的解决方案中。

    将 True Type Fonts (*.ttf) 文件添加到该文件夹​​

    将文件包含到项目中

    选择字体并将它们添加到解决方案中

    设置BuildAction: ResourceCopy To Output Directory: Do not copy。你的.csproj 文件现在应该有一个像这样的部分:

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

    App.xaml 添加&lt;FontFamily&gt; 资源。它应该类似于以下代码示例。请注意,在打包应用程序时,URI 不包含文件名。

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

    像这样应用你的字体:

     <TextBlock x:Name="myTextBlock" Text="foobar" FontFamily="StaticResource NotoSans" 
                FontSize="10.0" FontStyle="Normal" FontWeight="Regular" />
    

    你也可以强制设置字体:

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

复制到输出目录

    /Fonts 文件夹添加到您的解决方案中。

    将 True Type 字体 (*.ttf) 文件添加到该顺序

    将文件包含到项目中

    选择字体并将它们添加到解决方案中

    设置BuildAction: ContentCopy To Output Directory: Copy if newerCopy always。你的.csproj 文件现在应该有一个像这样的部分:

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

    App.xaml 添加&lt;FontFamily&gt; 资源。它应该类似于以下代码示例。

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

    像这样应用你的字体:

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

参考文献

MSDN: Packaging Fonts with Applications

【讨论】:

请说明#names 的来源以及它们的构造方式。只是文件名不带# 的扩展名?否则:很好,详细的答案! 哈希后的字符串是字体的名称。不幸的是,除了在预览中打开字体文件或安装它并在文本编辑器中使用字体选择之外,我真的不知道如何获得它们。可能有更好的方法来做到这一点...... 包选项在 VS2017 中对我不起作用。我完全按照你的指示去做了。 @JackMiller,我知道已经有一段时间了,但我也有同样的问题。您可以通过执行以下操作获得#names: 在 Windows 资源管理器中右键单击字体。转到属性 -> 详细信息 -> 标题。 仅供参考,神秘的#NotoSans 标识符不是由文件名驱动的。您需要在 Windows 中双击打开字体预览窗口的文件。会有一个标签,上面写着“字体名称:NotoSans”,这是您在 WPF 中引用时要使用的字体名称。【参考方案7】:

这对我有用:

(1) 将目录添加到项目中:字体

(2) 将ttf字体文件移动到字体目录中

(3) 将ttf字体文件添加到项目中

(4) 将tff字体文件的“Build”属性设置为“Resource” (注意:我使用“资源”而不是“嵌入式资源” 在组合框选择中。)

(5) 打开您正在使用该字体的窗口并制作 以下更改:

<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) 如果要从代码中更改字体。这样做:

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;
    

    ...

【讨论】:

【参考方案8】:

我试图让它与不同的字体一起工作, 它只适用于这种格式的 ./Fonts

&lt;FontFamily x:Key="NotoSans"&gt;pack://application:,,,./Fonts/#Noto Sans&lt;/FontFamily&gt;

【讨论】:

【参考方案9】:

首先)将字体复制到项目文件夹,如/Resources/Fonts/ 并设置字体属性 -> 构建操作:资源

第二)用于代码

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

【讨论】:

您将字体属性设置为 Build Action: Resource 的解决方案为我解决。只有你在 pack://application:,,,/AssemlyName;component/Resources/Fonts/#IRANSansWeb 中需要这个【参考方案10】:

您需要将字体添加为资源项

根据link;您可以按照以下步骤将所需字体添加为应用程序资源文件:

    在大多数情况下,将您的字体文件复制到项目中的任何位置,如果您想遵循此操作,资源文件将复制到名为“resources”的文件夹中,在您的项目中创建新文件夹并将其命名为“resources”然后将通常具有 ttf 或 otf 格式的字体文件复制到该文件夹​​中

    那么您需要将此文件声明为资源文件,这样做有两种选择:

      右键单击您的字体文件,选择属性(或选择后按 F4) 然后将 "Build Action" 更改为 "Resource"

      进入你的项目目录编辑project-name.csproj文件和 以下标签:

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

最后,在你的应用程序中,你可以像这样设置 font-family 属性:

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

小心 'font-name' 与 font-file-name 不同,您可以打开字体文件并检查字体名称属性(在 Microsoft Window 中)

【讨论】:

【参考方案11】:

包含外部字体的最简单方法是

第 1 步。 创建文件夹 Fonts 并将您的字体添加到其中。

第 2 步。 将 Build action 设置为 content 并将 Copy to Output Directory 设置为 Copy always

第 3 步。 构建解决方案以使用字体目录对其进行更新。

第 4 步。 在您的元素中使用字体FontFamily="Fonts/#font name"

全部完成!

感谢cscience!

【讨论】:

它对我有用,但仅限于设计师:/ 不要忘记字体名称区分大小写!【参考方案12】:

有点,真的很简单:

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

当您导入字体时,vs 会将其包含在字体列表中?。

【讨论】:

【参考方案13】:

虽然@movgp0 的解决方案起初有效,但当我想要一个粗体 文本时它失败了。通过在线搜索,我发现以下解决方案适用于所有情况:

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

用法:&lt;Label FontFamily="StaticResource FiraSansBold"&gt;SomeBoldedLabel&lt;/Label&gt;

【讨论】:

以上是关于如何在 WPF 应用程序中包含外部字体而不安装它的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Vuejs+Webpack 中包含外部 sass 目录?

如何在项目中包含/引用文件而不将其复制到项目目录?

在 Angular 2 + Meteor 应用程序中包含 Google 字体

如何在cordova ios应用程序中包含外部<img>标签

如何在 ARM 模板中包含外部逻辑应用实现

如何在 GWT 离线应用程序中包含外部 Javascript