2013-02-04 73 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