2013-02-04 72 views
1

我有一個WinForm項目。 我們使用字符串擴展方法「翻譯」來翻譯我們的消息通過翻譯文件。翻譯XAML元素

translatedString = myString.Translate() 

在那個projet中,我們使用了一些WPF控件。

我在WPF XAML控件中有類似的東西。

<MenuItem Name="tsmiCopier" 
     Header="Copier" 
     Command="Copy"> 

我需要翻譯「標題」中的文本。 所以我需要通過所有的「可翻譯的」XAML字符串通過Translate()函數。

換句話說,我需要做
tsmiCopier.Header = tsmiCopier.Header.Translate(),但所有的menuItems。也許不僅對於MenuItems,而且對於XAML中的其他「標題」,用戶可以在GUI中看到。

如何做得更好?

也許還有其他用於WPF翻譯的機制,但由於應用程序的其他部分,我們被迫使用獨特的Translate()方法。

+0

你是說了'myString'變量將包含值'<菜單項名稱=「tsmiCopier」標題=「複印機」命令=「複製」>'和你想要的'Translate'方法返回' 「複印機」'? –

+0

我需要做'tsmiCopier.Header = tsmiCopier.Header.Translate()' – serhio

回答

2

我回答這個與披露不必本地化的WPF應用程序。

這裏有幾個選項,可以幫助:

  1. 看看WPF Localization Extension

  2. 如果您必須使用Translate()方法,您可以創建一個轉換器。有幾種方法可以轉換該值,無論是通過直接綁定,還是通過繞過Binding表達式的參數。

XAML

<Window x:Class="so.Localization.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:Localization="clr-namespace:so.Localization" Title="Tranlate" 
     Width="525" 
     Height="350" 
     WindowStartupLocation="CenterScreen"> 
    <Window.Resources> 
     <Localization:TranslateConverter x:Key="Translater" /> 
    </Window.Resources> 
    <Grid> 
     <Menu> 
      <MenuItem Header="{Binding Converter={StaticResource Translater}, ConverterParameter='Copier', FallbackValue='Copier'}" /> 
     </Menu> 
    </Grid> 
</Window> 

代碼後面

using System; 
using System.Globalization; 
using System.Windows; 
using System.Windows.Data; 

namespace so.Localization 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
    } 

    [ValueConversion(typeof(string), typeof(string))] 
    public class TranslateConverter : IValueConverter 
    { 
     #region Implementation of IValueConverter 

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      // if using binding 
      if(value != null && value is string) 
      { 
       return ((string)value).TranslateBinding(); 
      } 

      // if using a general paramater 
      if(parameter != null && parameter is string) 
      { 
       return ((string)parameter).TranslateParameter(); 
      } 

      return DependencyProperty.UnsetValue; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 

     #endregion 
    } 

    public static class Ext 
    { 
     public static string TranslateBinding(this string input) 
     { 
      // translat to whatever... 
      return input + " (translated binding)"; 
     } 

     public static string TranslateParameter(this string input) 
     { 
      // translat to whatever... 
      return input + " (translated parameter)"; 
     } 
    } 
} 
+1

如果DataContext碰巧是一個字符串,將會中斷,因爲它將使用該字符串而不是參數。爲了強制它,應該在Binding上明確設置Source,或者複製到'Copier'或{x:Null}。 –

+1

@JohnBowen - 同意 - 我做了這樣的假設,OP會理解樣本被提供爲使用另一個,並且會更新轉換器以檢查綁定或參數,但不是兩者。 –

0

一個)

Public Sub TranslateHeaderedItemsLogical(ByVal myFrameworkElement As FrameworkElement) 
    For Each element In LogicalTreeHelper.GetChildren(myFrameworkElement) 
     If TypeOf element Is HeaderedItemsControl Then 
     Dim objHeaderedVisual As HeaderedItemsControl = DirectCast(element, HeaderedItemsControl) 
     If (objHeaderedVisual.Header IsNot Nothing) Then 
      objHeaderedVisual.Header = objHeaderedVisual.Header.ToString().Translate() 
     End If 
     End If 
    Next element 
    End Sub 

B)

Private Sub MyWPFControl_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded 
    TranslateHeaderedItemsLogical(Me.ContextMenu) 
    End Sub