2011-07-28 24 views
5

如果安裝了我們的設計,我們的設計更喜歡使用Century Gothic,但如果它沒有可用的話,則會回退到Arial或Lucidia。這在大部分情況下工作正常,除非機器沒有安裝世紀哥特,但沒有有Century(這似乎是很多沒有Office的XP機器)。 「有用地」用世紀哥特替代世紀,這是可怕的,並且是襯線字體,完全忽略了我們的後備字體。使用Century取代世紀哥特王朝的WPF

這是容易複製由與世紀,而不是世紀的哥特式機器,然後創建一個TextBlock如:

<TextBlock FontFamily="Century Gothic, Wingdings">Should be gibberish</TextBlock> 

應該顯示爲亂碼宋體,而是它顯示難看,但可讀的世紀。

我試過在compositefont包裹世紀的哥特式,但具有相同的問題:

<FontFamily 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/composite-font" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:System="clr-namespace:System;assembly=mscorlib"> 
    <FontFamily.FamilyNames> 
    <System:String x:Key="en-US">CenturyGothic</System:String> 
    </FontFamily.FamilyNames> 
    <FontFamily.FamilyTypefaces> 
    <FamilyTypeface Weight="Normal" Stretch="Normal" Style="Normal" /> 
    <FamilyTypeface Weight="Bold" Stretch="Normal" Style="Normal" /> 
    </FontFamily.FamilyTypefaces> 
    <FontFamily.FamilyMaps> 
    <FontFamilyMap Target="Century Gothic" Scale="1" /> 
    </FontFamily.FamilyMaps> 
</FontFamily> 

嵌入字體不是一個選項(許可) - 有什麼辦法來強制其忽略世紀,還是我辭職改變它使用不同的字體?

編輯:我剛剛嘗試過使用FontFace =「'世紀哥特式',Wingdings」,但從未顯示世紀哥特式,即使它已安裝。

+0

我無法確定,但字體選擇模型在http://blogs.msdn.com/b/text/archive/2007/04/23/wpf-font-selection-model中的PDf中概述。 aspx。雖然這可能沒有太大的幫助,但我的目光掠過,只是想看看它。 –

回答

0

好吧,目前我有一個工作,如果有點笨拙的感覺,解決方案。我有一個靜態輔助類,它看起來是這樣的:

namespace FontFallbackTest 
{ 
    using System.Linq; 
    using System.Windows.Markup; 
    using System.Windows.Media; 

    public static class FontHelper 
    { 
     private static readonly FontFamily testFont; 
     public static FontFamily TestFont 
     { 
      get 
      { 
       return testFont; 
      } 
     } 

     static FontHelper() 
     { 
      testFont = new FontFamily(); 

      testFont.FamilyNames.Add(XmlLanguage.GetLanguage("en-US"), "TestFont"); 

      if (Fonts.SystemFontFamilies.Any(f => f.FamilyNames.Any(kv => kv.Value == "Century Gothic"))) 
      { 
       testFont.FamilyMaps.Add(new FontFamilyMap() { Target = "Century Gothic" }); 
      } 

      testFont.FamilyMaps.Add(new FontFamilyMap() { Target = "Comic Sans MS", Scale = 0.5 }); 
     } 
    } 
} 

然後我在我的XAML中引用這樣的:

<Window x:Class="FontFallbackTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:FontFallbackTest="clr-namespace:FontFallbackTest" 
     Title="MainWindow" Height="550" Width="525"> 
    <Grid> 
     <Label Margin="0,100,0,0" FontSize="48" FontFamily="{x:Static FontFallbackTest:FontHelper.TestFont}">This is some text</Label> 
     <Label Margin="0,150,0,0" FontSize="48" FontFamily="{x:Static FontFallbackTest:FontHelper.TestFont}">This is more text</Label> 
    </Grid> 
</Window> 

這似乎是工作 - 顯示世紀的哥特式,忽略世紀,讓我控制回退的字體縮放。

1

A到字體完全合格的路徑可能做的伎倆:

<TextBlock Margin="20" FontFamily="c:\windows\fonts\GOTHIC.TTF#Century Gothic, Wingdings">Should be gibberish</TextBlock> 

硬編碼的路徑是不理想的,但你可以添加一個回退,在案件中使用的字體的友好名稱的用戶正在運行通過非標準的安裝路徑。您也可以使用代碼來查找註冊表中的字體目錄並使用它。

另一種選擇可能是使用代碼遍歷已安裝的字體,並選擇一個你想要的方式。 System.Windows.Media.Fonts.SystemFontFamilies已安裝字體。一旦你找到你想要的字體,你可以將該字體族對象分配給控件,而不是讓它解析一個字符串。

+0

不理想?好的。 –

+1

這不起作用,但通過Windows目錄引用它是一個等待發生的事故(並且%windir%不起作用)。 –

1

這個問題似乎是WPF通過Family而不是Face來搜索字體。在你的場景中,Century和Century Gothic都是Century系列字體的一部分。因此,您需要將所有面都映射到您想要的面。請確認這適用於你:

<Label Content="Hello World" FontSize="32"> 
    <Label.FontFamily> 
     <FontFamily xmlns:sys="clr-namespace:System;assembly=mscorlib"> 
      <FontFamily.FamilyNames> 
       <sys:String x:Key="en-US">Century, Century Gothic, Century Schoolbook</sys:String> 
      </FontFamily.FamilyNames> 
      <FontFamily.FamilyMaps> 
       <FontFamilyMap Target="Century Gothic" /> 

       <!-- used when Century Gothic is not available --> 
       <FontFamilyMap Target="Arial" /> 
      </FontFamily.FamilyMaps> 
     </FontFamily> 
    </Label.FontFamily> 
</Label> 
+0

啊,有趣的是,從來沒有想過將世紀添加到字體家族中 - 我已經閱讀過WPF關於它如何選擇字體的論文,並且似乎沒有提及任何關於假設類似命名的字體是同一個家族的內容。如果我有機會,我會在今天放棄它。 –

+0

不幸的是,這不起作用 - 它有完全相同的問題 - 在裝有Century的機器上,而不是Century哥特式,這個標籤顯示爲Century,而不是Arial。 –

+0

我在win xp pro,.net 4上測試過它,它的行爲如預期。我不知道OS和框架版本是否有影響? – sellmeadog

2

您可以使用WPF樣式和合並資源字典進行此操作。

創建兩個資源字典,一個是默認的字體,以及一個爲你的後備字體:

DefaultFonts.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Style TargetType="TextBlock"> 
     <Setter Property="FontFamily" Value="Century Gothic"/> 
    </Style> 
</ResourceDictionary> 

FallbackFonts.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Style TargetType="TextBlock"> 
     <Setter Property="FontFamily" Value="Arial"/> 
    </Style> 
</ResourceDictionary> 

添加這兩個文件到您的項目並將它們的構建動作設置爲資源

下面的代碼添加到您的應用程序的啓動:

public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    {    
     base.OnStartup(e); 

     string fontsResourcePath = "/DefaultFonts.xaml"; 
     if (!Fonts.SystemFontFamilies.Any(f => f.FamilyNames.Any(kv => kv.Value == "Century Gothic"))) 
     { 
      fontsResourcePath = "/FallbackFonts.xaml"; 
     } 
     this.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(fontsResourcePath, UriKind.Relative) }); 
    } 
} 

這樣做,這樣會自動設置上的所有控件正確的字體在整個應用程序(除非你在本地覆蓋窗口,網頁上的字體,或控制)。

例子:

<Grid> 
    <TextBlock>This will show as Century Gothic or fall back to Arial</TextBlock> 
</Grid> 

編碼愉快!