How to localize inline strings in schedule month view without changing locale in device ?
You can localize the custom strings (All Day, No Events) used in the schedule control month inline view from PCL without changing locale in device. It can be achieved by providing the custom strings to the specific language resx file and handling the required culture with the locale using DependencyService instead of device language. In the below code, we have set French as Schedule locale as well as custom strings.
Step 1: Sample changes, setting locale
// Here LocaleFromPCL is a sample name. ScheduleResourceManager.Manager = new ResourceManager("LocaleFromPCL.Resources.Syncfusion.SfSchedule.Forms", GetType().GetTypeInfo().Assembly); if (schedule.Locale == "fr") { if (Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.Android) { DependencyService.Get<ILocalize>().SetLocale(new CultureInfo("fr")); } else { CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("fr"); } }
Step 2: Adding resx file in pcl
You need to add the required resx files under the Resources folder in the PCL project and the filename should be Syncfusion.SfSchedule.Forms.LanguageCode.resx.
Example: For French, Syncfusion.SfSchedule.Forms.fr.resx
Now, set the Build Action as EmbeddedResource for Syncfusion.SfSchedule.Forms.fr.resx file and Build Action as Compile for Syncfusion.SfSchedule.Forms.fr.Designer.cs file.
<!--</CustomStrings>--> <data name="NoEvents" xml:space="preserve"> <value>Pas d'événements</value> </data> <data name="AllDay" xml:space="preserve"> <value>Toute la journéer</value> </data>
Step 3: Adding ILocalize interface in PCL
You need to add the ILocalize interface to convert the platform-specific locales to a value supported in .NET cultures in the PCL project.
/// <summary> /// Implementations of this interface MUST convert iOS and Android /// platform-specific locales to a value supported in .NET because /// ONLY valid .NET cultures can have their RESX resources loaded and used. /// </summary> public interface ILocalize { /// <summary> /// This method must evaluate platform-specific locale settings /// and convert them (when necessary) to a valid .NET locale. /// </summary> CultureInfo GetCurrentCultureInfo(); /// <summary> /// CurrentCulture and CurrentUICulture must be set in the platform project, /// because the Thread object can't be accessed in a PCL. /// </summary> void SetLocale(CultureInfo ci); } /// <summary> /// Helper class for splitting locales like /// iOS: ms_MY, gsw_CH /// Android: in-ID /// into parts so we can create a .NET culture (or fallback culture) /// </summary> public class PlatformCulture { public PlatformCulture(string platformCultureString) { if (String.IsNullOrEmpty(platformCultureString)) throw new ArgumentException("Expected culture identifier", "platformCultureString"); // in C# 6 use nameof(platformCultureString) PlatformString = platformCultureString.Replace("_", "-"); // .NET expects dash, not underscore var dashIndex = PlatformString.IndexOf("-", StringComparison.Ordinal); if (dashIndex > 0) { var parts = PlatformString.Split('-'); LanguageCode = parts[0]; LocaleCode = parts[1]; } else { LanguageCode = PlatformString; LocaleCode = ""; } } public string PlatformString { get; private set; } public string LanguageCode { get; private set; } public string LocaleCode { get; private set; } public override string ToString() { return PlatformString; } }
Step 4: Adding Localize class in Android and iOS project inheriting from ILocalize
You need to add the Localize class in Android and iOS project by inheriting from ILocalize. You can get the CultureInfo and set the same to Schedule Locale by using GetCurrentCultureInfo and SetLocale.
Localize class for Android project,
[c#]
public class Localize : ILocalize { public void SetLocale(CultureInfo ci) { Thread.CurrentThread.CurrentCulture = ci; Thread.CurrentThread.CurrentUICulture = ci; } public CultureInfo GetCurrentCultureInfo() { var netLanguage = "en"; var androidLocale = Java.Util.Locale.Default; netLanguage = AndroidToDotnetLanguage(androidLocale.ToString().Replace("_", "-")); // this gets called a lot - try/catch can be expensive so consider caching or something CultureInfo ci = null; try { ci = new CultureInfo(netLanguage); } catch { // iOS locale not valid .NET culture (eg. "en-ES" : English in Spain) // fallback to first characters, in this case "en" try { var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage)); ci = new CultureInfo(fallback); } catch { // iOS language not valid .NET culture, falling back to English ci = new CultureInfo("en"); } } return ci; } private string AndroidToDotnetLanguage(string androidLanguage) { var netLanguage = androidLanguage; //certain languages need to be converted to CultureInfo equivalent switch (androidLanguage) { case "ms-BN": // "Malaysian (Brunei)" not supported .NET culture case "ms-MY": // "Malaysian (Malaysia)" not supported .NET culture case "ms-SG": // "Malaysian (Singapore)" not supported .NET culture netLanguage = "ms"; // closest supported break; case "in-ID": // "Indonesian (Indonesia)" has different code in .NET netLanguage = "id-ID"; // correct code for .NET break; case "gsw-CH": // "Schwiizertüütsch (Swiss German)" not supported .NET culture netLanguage = "de-CH"; // closest supported break; // add more application-specific cases here (if required) // ONLY use cultures that have been tested and known to work } return netLanguage; } private string ToDotnetFallbackLanguage(PlatformCulture platformCulture) { var netLanguage = platformCulture.LanguageCode; // use the first part of the identifier (two chars, usually); switch (platformCulture.LanguageCode) { case "gsw": netLanguage = "de-CH"; // equivalent to German (Switzerland) for this app break; // add more application-specific cases here (if required) // ONLY use cultures that have been tested and known to work } return netLanguage; } }
Localize class for iOS project,
public class Localize : ILocalize { public void SetLocale(CultureInfo ci) { Thread.CurrentThread.CurrentCulture = ci; Thread.CurrentThread.CurrentUICulture = ci; } public CultureInfo GetCurrentCultureInfo() { var netLanguage = "en"; if (NSLocale.PreferredLanguages.Length > 0) { var pref = NSLocale.PreferredLanguages[0]; netLanguage = iOSToDotnetLanguage(pref); } // this gets called a lot - try/catch can be expensive so consider caching or something CultureInfo ci = null; try { ci = new CultureInfo(netLanguage); } catch { // iOS locale not valid .NET culture (eg. "en-ES" : English in Spain) // fallback to first characters, in this case "en" try { var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage)); ci = new CultureInfo(fallback); } catch { // iOS language not valid .NET culture, falling back to English ci = new CultureInfo("en"); } } return ci; } private string iOSToDotnetLanguage(string iOSLanguage) { var netLanguage = iOSLanguage; //certain languages need to be converted to CultureInfo equivalent switch (iOSLanguage) { case "ms-MY": // "Malaysian (Malaysia)" not supported .NET culture case "ms-SG": // "Malaysian (Singapore)" not supported .NET culture netLanguage = "ms"; // closest supported break; case "gsw-CH": // "Schwiizertüütsch (Swiss German)" not supported .NET culture netLanguage = "de-CH"; // closest supported break; // add more application-specific cases here (if required) // ONLY use cultures that have been tested and known to work } return netLanguage; } private string ToDotnetFallbackLanguage(PlatformCulture platCulture) { var netLanguage = platCulture.LanguageCode; // use the first part of the identifier (two chars, usually); switch (platCulture.LanguageCode) { // case "pt": netLanguage = "pt-PT"; // fallback to Portuguese (Portugal) break; case "gsw": netLanguage = "de-CH"; // equivalent to German (Switzerland) for this app break; // add more application-specific cases here (if required) // ONLY use cultures that have been tested and known to work } return netLanguage; } }