Xamarin.Forms : How to use localization independent of device language
Asked Answered
L

3

14

I am developing a Xamarin.Forms app (portable class library project) with Visual Studio 2013 CE. First I'm focusing the iOS version.

Now I'm thinking about how to make the app multilingual. I just read the offical Xamarin documentation about it but i realized that this solution only takes the system language of the target device.

In the portable class library I have a Resources folder with three languages: German (default), English and French.

Resource.resx
Resource.en-US.resx
Resource.fr-FR.resx
Resource.Designer.cs

Now i just created a static settings class which looks like this:

public static class Settings
{
    public static Dictionary<String, CultureInfo> Languages = new Dictionary<String, CultureInfo> { { "German", new CultureInfo("de-DE") }, { "English", new CultureInfo("en-US") }, { "French", new CultureInfo("fr-FR") } };

    public static CultureInfo CurrentCulture = Languages["German"];
    public static CultureInfo CurrentUiCulture = Languages["German"];

    public static void ChangeCurrentCultureInfo(CultureInfo cultureInfo)
    {
        Resource.Culture = cultureInfo;
    }
}

Now my question is if it's possible to change the culture in the application while runtime with a button click. Maybe something like

Settings.CurrentCulture = Settings.Languages["English"];
Settings.ChangeCurrentCultureInfo(Settings.CurrentCulture);

Does anyone can tell me how this can be done?

Regards

Liz answered 16/2, 2015 at 14:0 Comment(0)
L
7

Finally i got an answer of the Xamarin support. The solution i was thinking about works. In the PCL i just have the static Settings class which stores the different CultureInfo objects. In addition I defined a method for changing the current culture and the language of the resources file.

public static void ChangeCurrentCultureInfo(CultureInfo cultureInfo)
{
    CurrentCulture = cultureInfo;
    Resource.Culture = CurrentCulture;
}

It was important to set the default language in the App() constructor before I initialize the main page. Now i got a listview with all supported languages with one tapped event which calls the ChangeCurrentCultureInfo method.

Nevertheless i want to thank Andy Hopper for providing his solution!

Regards

Liz answered 18/2, 2015 at 14:27 Comment(5)
What does Resource mean here?Tranquilizer
@EmrahAkgül I edited my question. Resource is the resx file which stores the default language.Liz
@yehe I'm sorry I can't share code because this is a project of an old job. =(Liz
why do you store default language in the resource file? most important how do you store? I thought resx files are only for translations. There is already build-in application setting i think.Oxendine
yehe, can you possibly share a small code sample of your solution?Infliction
N
14

I don't believe you can do this from within your shared PCL project. However, you CAN set the UICulture from within your platform-specific projects. To do this from a useful location (i.e., your Forms app), we must expose this as a service from your platform projects as a dependency.

First, define the interface that describes your culture management "service." This should live in an assembly that is referenced by your platform-specific projects (the shared PCL project will do):

public interface ICultureInfo
{
    System.Globalization.CultureInfo CurrentCulture { get; set; }
    System.Globalization.CultureInfo CurrentUICulture { get; set; }
}

And in each of your platform projects, include a type that implements that interface:

using System;
using Xamarin.Forms;
using System.Threading;

[assembly:Dependency(typeof(YourNamespaceHere.PlatformCultureInfo))]
namespace YourNamespaceHere
{
    public class PlatformCultureInfo : ICultureInfo
    {
        #region ICultureInfo implementation

        public System.Globalization.CultureInfo CurrentCulture {
            get {
                return Thread.CurrentThread.CurrentCulture;
            }
            set {
                Thread.CurrentThread.CurrentCulture = value;
            }
        }

        public System.Globalization.CultureInfo CurrentUICulture {
            get {
                return Thread.CurrentThread.CurrentUICulture;
            }
            set {
                Thread.CurrentThread.CurrentUICulture = value;
            }
        }

        #endregion
    }
}

Then in your forms app, you request an instance of the platform's implementation from the Xamarin Forms DependencyService. (NOTE: Any calls to the DependencyService must happen AFTER a call to Forms.Init())

Once you retrieve it, you can set the current UI culture:

var cultureInfo = Xamarin.Forms.DependencyService.Get<ICultureInfo>();
cultureInfo.CurrentUICulture = new System.Globalization.CultureInfo("fr-FR");

Et voila, any changes to the UI culture will be reflected with any subsequent resource lookups. Note the use of the word "subsequent" - any forms using resource lookups (such as if you're using my handy localization XAML markup extensions) won't reflect the culture change until they are refreshed/reloaded.

In closing, the Xamarin team did a great job duplicating the original resource lookup infrastructure! It just needs a little push to get it into the world of Xamarin Forms.

Negatron answered 17/2, 2015 at 17:13 Comment(4)
Thank you very much for your answer! I will try this out! Can you tell me how to refresh/reload a view in the best way?Liz
The easiest way would be to set the MainPage of your app to a new instance of the page. If you're using the MVVM pattern, you can preserve the page's state by re-using the ViewModel.Negatron
This solution translate javascript:void(0)so throw exception? catch (Exception ex) { Debug.Writeline(ex.Message); }Daggerboard
How do I refresh a content page? Or the whole forms app?Hyacinthie
L
7

Finally i got an answer of the Xamarin support. The solution i was thinking about works. In the PCL i just have the static Settings class which stores the different CultureInfo objects. In addition I defined a method for changing the current culture and the language of the resources file.

public static void ChangeCurrentCultureInfo(CultureInfo cultureInfo)
{
    CurrentCulture = cultureInfo;
    Resource.Culture = CurrentCulture;
}

It was important to set the default language in the App() constructor before I initialize the main page. Now i got a listview with all supported languages with one tapped event which calls the ChangeCurrentCultureInfo method.

Nevertheless i want to thank Andy Hopper for providing his solution!

Regards

Liz answered 18/2, 2015 at 14:27 Comment(5)
What does Resource mean here?Tranquilizer
@EmrahAkgül I edited my question. Resource is the resx file which stores the default language.Liz
@yehe I'm sorry I can't share code because this is a project of an old job. =(Liz
why do you store default language in the resource file? most important how do you store? I thought resx files are only for translations. There is already build-in application setting i think.Oxendine
yehe, can you possibly share a small code sample of your solution?Infliction
M
0

you can call setLocale method available in each platform projects from PCL using the interface ILocalize like this:

CultureInfo ci=new CultureInfo("ar");
Xamarin.Forms.DependencyService.Get<ILocalize>().SetLocale(ci);                      

AppResources.Culture = ci;
Macrophage answered 5/10, 2018 at 17:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.