翻译XAML元素

本文关键字:元素 XAML 翻译 | 更新日期: 2023-09-27 17:57:49

我有一个WinForm项目。我们使用字符串扩展方法"Translate"通过翻译文件翻译我们的消息。

translatedString = myString.Translate()

在该项目中,我们使用了一些WPF控件。

我在WPF XAML控件中有这样的东西。

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

我需要翻译"页眉"中的文字。因此,我需要通过Translate()函数传递所有"可翻译"的XAML字符串。

换句话说,我需要做
tsmiCopier.Header = tsmiCopier.Header.Translate(),但适用于所有菜单项。也许不仅对于MenuItems,而且对于XAML中的其他"标头",用户可以在GUI中看到。

如何做得更好?

也许WPF翻译还有其他机制,但由于应用程序的其余部分,我们不得不使用唯一的Translate()方法。

翻译XAML元素

我在回答这个问题时公开了不必本地化WPF应用程序。

这里有几个选项可能会有所帮助:

  1. 看看WPF本地化扩展。

  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)";
        }
    }
}

a)

  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