2009-09-24 211 views
0

我正在處理的項目有一個豐富的文本框,可以通過組合框將其字體更改爲任何系統字體。C#WPF獲取本地化的FontFamily

我們將所有來自「Fonts.SystemFontFamilies」的FontFamily對象添加爲組合框的ItemsSource。如果它們存在於每個FontFamily中,我們需要能夠顯示這些字體的本地化名稱。

我目前假設我們看到爲每個ComboBoxItem顯示的文本是我們設置爲ItemsSource的FontFamily對象的Source屬性。有沒有簡單的方法來本地化這個來源?我已經能夠得到使用本地化的名稱:

font.FamilyNames.TryGetValue(XmlLanguage.GetLanguage("ja-JP"), out name); 

但FontFamily.Source是隻讀的,我無法將這個新名稱分配到的FontFamily對象。

- 更新 -

我們決定不使用包含字體系列的一類,由於與應用集成起來併發症。我想嘗試使用一個值轉換器來避免更改底層代碼。

我有以下的值轉換器類:

class FontValueConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     FontFamily font = (FontFamily)value; 
     string localizedName = font.FamilyNames[XmlLanguage.GetLanguage(culture.Name)]; 

     if (!String.IsNullOrEmpty(localizedName)) 
      return localizedName; 

     return font.ToString(); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException("ConvertBack not supported"); 
    } 
} 

我試圖把它綁定到ComboBoxItem對象。我們在後面的代碼中設置ItemsSource;基本上是「ItemsSource = collectionOfFonts」。我想要做的是將我的轉換器綁定到ItemsSource中的每個項目,以便它將轉換爲本地化的字體系列名稱。

我一直在考慮下面的XAML代碼:

  <Style 
      x:Key="ComboBoxItemStyle" 
      TargetType="{x:Type ComboBoxItem}"> 
      <Setter 
       Property="Template"> 
       <Setter.Value> 
        <ControlTemplate 
         TargetType="{x:Type ComboBoxItem}"> 
         <ContentPresenter 
          Content="{Binding Source=..., Converter={StaticResource FontValueConverter}}" /> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

不過,我很困惑,我該怎麼綁定,因此檢索的FontFamily對象,並將其轉換爲字符串,返回的值顯示。

有什麼想法?

回答

1

我們發現,只需要很少的更改應用程序的其餘部分最簡單的解決辦法是實例化如果可用,則使用字體的本地化名稱的新FontFamily對象。這是通過創建以下方法,它返回如有必要,一個新的FontFamily對象來完成:

private FontFamily GetLocalizedFontFamily(FontFamily font) 
    { 
     string localizedName = font.FamilyNames[XmlLanguage.GetLanguage(CultureInfo.CurrentUICulture.Name)]; 
     if (!String.IsNullOrEmpty(localizedName)) 
      return new FontFamily(localizedName); 

     return font; 
    } 

使用這種方法意味着我們只需要改變其中的項目添加到組合框的代碼,絕對沒有變化所需別處。使用

例子:

foreach (FontFamily font in Fonts.SystemFontFamilies) 
{ 
    FontFamily localizedFont = GetLocalizedFontFamily(font); 
    FontFamilyComboBox.Items.Add(localizedFont); 
} 
0

考慮一個自定義的值轉換器,利用您所顯示的代碼,這應該允許您輕鬆地綁定到字體家族枚舉,同時提供本地化名稱(如果可用)。 TypeConverter只能用於內容綁定,例如您不想在組合框中翻譯FontFamily本身,您只需要在項目/數據模板中將其用於文本顯示。

或者,您可以生成一個容器對象,該對象除了「FontFamily」屬性外還公開一個「DisplayName」屬性,其中DisplayName是您希望的本地化結果。針對SelectedItem(或類似)的綁定必須在綁定路徑中包含「FontFamily」屬性才能繼續運行。

希望有所幫助。

+0

我會給自定義值轉換器一個走了不久。這似乎是更好的解決方案。 – Jason 2009-09-25 09:15:43

+0

是否有可能從C#代碼而不是XAML添加值轉換器? – Jason 2009-09-28 10:50:09

+0

您可以通過xaml註冊代碼的方式註冊代碼轉換器,例如通過在代碼中構建您的綁定而不是xaml。我不知道有任何其他方式註冊轉換器,除非通過綁定。我相信你可以直接調用它們,但是我從來沒有這樣做過,我懷疑你可以直接調用它們,並且仍然可以從枚舉值列表(或類似的列表)中獲得貨幣/數據綁定的好處使用價值轉換器。 – 2009-09-29 12:42:40

0

我們最終的解決方案是創建一個名爲LocalizedFontFamily的新類。由於FontFamily是密封的,我們不能擴展它,所以我們將它作爲參數傳遞給LocalizedFontFamily類構造函數。

我們給這個類中的ToString方法,將得到本地化的字體名稱,如果可能的返回它:

public override string ToString() 
    { 
     string localizedName = fontFamily.FamilyNames[XmlLanguage.GetLanguage(CultureInfo.CurrentUICulture.Name)]; 

     if (!String.IsNullOrEmpty(localizedName)) 
      return localizedName; 

     return fontFamily.ToString(); 
    } 
+0

我們已經決定不使用這種方法,因爲這有很多連鎖效應,其他地方和項目是巨大的。 – Jason 2009-10-14 14:50:27