serhio
serhio

Reputation: 28586

Translate XAML elements

I have a WinForm project. We use a string extension method "Translate" to translate our messages via translation files.

translatedString = myString.Translate()

In that projet we use some WPF controls.

I have something like this in a WPF XAML control.

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

I need to translate text in the "Header". So I need to pass all the "translatable" XAML strings via that Translate() function.

In other words, I need to do
tsmiCopier.Header = tsmiCopier.Header.Translate(), but for all the menuItems. And perhaps not only for the MenuItems, but alto other "headers" in the XAML, that user can see in the GUI.

How to do it better?

Perhaps there are other mecanisms for WPF translation, but we are forced to use the unique Translate() method because of the rest of the application.

Upvotes: 1

Views: 4031

Answers (2)

serhio
serhio

Reputation: 28586

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

Upvotes: 0

Metro Smurf
Metro Smurf

Reputation: 38385

I'm answering this with the disclosure of not having to localize a WPF application.

Here are a couple of options that may help:

  1. Take a look at WPF Localization Extension.

  2. If you have to use the Translate() method, you could create a converter. There are a couple of ways you could translate the value, either by direct binding, or through a parameter which bypasses the Binding expression.

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>

Code Behind

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

Upvotes: 2

Related Questions