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
Xamarin. Essentials provides a single cross-platform API that works with any iOS, Android, or UWP application that can be accessed from shared code no matter how the user interface is created. See the platform & feature support guide for more information on supported operating systems.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With