0

I want to make my WPF window multilanguage. I have already read this post. Instead of using resx file, I want that the translations are performed by an instance of my class that is the translation responsable because I use it also in other points of the application.

I thought to implement the Binding with a converter which receives the key value that has to be translated. I don't know if this is the best approach or if there are any better solution.

Any help is really appreciate! Thanks.

Community
  • 1
  • 1
ctt_it
  • 339
  • 1
  • 6
  • 22

2 Answers2

0

That is a good approach. You can write a MarkupExtension to handle the translations. use it like so:

<TextBlock Text="{MyNameSpace:Translate 'good night'}"/>

The MarkupExtension will be responsible to go to your class/service to translate that string and return it.

That way you dont need to have unnecesary Bindings and Converters.

Mishka
  • 508
  • 3
  • 5
  • Thank you! I have followed this guide http://10rem.net/blog/2011/03/09/creating-a-custom-markup-extension-in-wpf-and-soon-silverlight and I have implemented my CustomMarkupExtension. How can I "go to my class/service" from the markup-extension? Must it be a static class? Thank you! – ctt_it Apr 06 '17 at 08:10
  • Probably I found the solution: http://stackoverflow.com/questions/3047448/accessing-current-class-from-wpf-custom-markupextension – ctt_it Apr 06 '17 at 08:14
  • Yes, either that or by using some sort of service locator, to get an implementation of an interface, which your class will do. – Mishka Apr 06 '17 at 08:40
0

This is the solution I found:

public class TranslateMarkupExtension : MarkupExtension
{
    [ConstructorArgument("value1")]
    public string Value1 { get; set; }

    public TranslateMarkupExtension() { }

    public TranslateMarkupExtension(string value1)
    {
        Value1 = value1;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var rootObjectProvider = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
        var root = rootObjectProvider.RootObject;

        var translation = GetLangTranslator(root);

        return string.IsNullOrEmpty(translation) ? Value1 :translation;
    }

    private string GetLangTranslator(object root)
    {
        var properties = root.GetType().GetProperties();

        foreach (var property in properties)
        {
            if (typeof(MultiLanguage) == property.PropertyType)
            {                   
                var m = property.PropertyType.GetMethod("Translate");

                var propValue = property.GetValue(root);
                return m.Invoke(propValue, new object[] {Value1}) as string;
            }
        }

        return null;
    }
}

Now I have just to find how to update the UI when the language change runtime.

ctt_it
  • 339
  • 1
  • 6
  • 22
  • https://wpftutorial.net/LocalizeMarkupExtension.html This is the final part in order to have the language change runtime – ctt_it Apr 11 '17 at 13:17