Managing Strings for Localization in Tizen .NET Applications
Eden Lee
Staff Engineer
Localization is the process of adapting an application to a specific country or region. To do this, an application should translate an application’s resources, such as text and images, into multiple languages and formats. Then, the application shows localized resources based on the settings of the device.
This post explains how to localize text in Tizen .NET application. I strongly recommend you to read Xamarin.Forms String and Image Localization before you get started. You can obtain the sample application used in this post here.
Create resource files
The .NET framework provides a way for localizing an application using Resx resource files. Each file contains a list of items that consist of a name/value pair and an application can retrieve a specific resource by name. By using this mechanism, you can store and retrieve localized texts.
-
Create a default resource file.
Using Add New Item dialog, add a default resource file. The file name of the default resource doesn’t contain any language information. In the sample application, the default resource file AppResources.resx is added to the Resources folder.
Set the Access Modifier to Public, which results in a file with the .designer.cs extension being added to the project. Then, add items which contain the following information:- Name : The key used to retrieve the text
- Value : The localized text
- Comment : Additional information (optional)
-
Add additional resource files.
Create additional resource files for each language you want to support. The file name of each resource should include the language information, such as AppResources.ko-KR.resx. In these resource files, set the Access Modifier to No code gen.
The file name of resource can include just the language code, without a country code, such as AppResource.es.resx. If the language of the device is es-ES, the application looks for resource files in this order:- AppResources.es-ES.resx
- AppResources.es.resx
- AppResources.resx (default)
Specify the default language
Specify a default language using NeutralResourcesLanguage to inform the resource manager of the app’s default language. This improves lookup performance for the first resource that is loaded. In the sample application, en (English) is set by NeutralResourcesLanguage in Main.cs. For more information about NeutralResourcesLanguage, see NeutralResourcesLanguage Attribute Class.
using System.Resources;
[assembly: NeutralResourcesLanguage("en")]
Localize texts
The language setting of a device can be changed when your application is running. To adapt your application to the new language, text needs to be translated on the fly. XAML markup extensions is a good solution to meet this requirement and this is where we will start with my own LocalizingExtension class.
[ContentProperty("Name")]
public class LocalizingExtension : IMarkupExtension<BindingBase>
{
private static readonly IValueConverter _converter = new LocalizedResourceConverter();
public string Name { get; set; }
public BindingBase ProvideValue(IServiceProvider serviceProvider)
{
return new Binding(nameof(LocalizationService.UICulture), BindingMode.OneWay, converter: _converter, converterParameter: Name, source: LocalizationService.Instance);
}
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
return (this as IMarkupExtension<BindingBase>).ProvideValue(serviceProvider);
}
}
This extension enables a text to be localized when an application is started and the language setting is changed. This extension has a single property Name of type string that you set to the name of the text to be localized. This Name property is the content property, so Name=
is not required when using it in XAML.
I also made a LocalizationService class which provides information about the current language and notifies clients that the language setting has changed. You can see the code here.
In addition, the LocalizationService class provides a method to get localized text. This function uses ResourceManager defined in AppResources.Designer.cs.
/// <summary>
/// Get the value of localized resource.
/// </summary>
/// <param name="resourceName">Resource name</param>
/// <returns>
/// The value of localized resource.
/// If resourceName is not defined as a name in any resource file, then resourceName is returned as the value of the resource.
/// </returns>
public string GetResource(string resourceName)
{
return AppResources.ResourceManager.GetString(resourceName, UICulture) ?? resourceName;
}
By using this method, the LocalizedResourceConverter class converts text to the localized text.
public class LocalizedResourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return LocalizationService.Instance.GetResource(parameter as string);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Accessing the value of text by LocalizingExtension enables localized text to be displayed even if the language setting of device has been changed.
<ContentPage
x:Class="LocalizationSample.Views.CenterLayoutPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ext="clr-namespace:LocalizationSample.Extensions"
xmlns:viewModels="clr-namespace:LocalizationSample.ViewModels">
<ContentPage.BindingContext>
<viewModels:CenterLayoutViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout Margin="0, 40, 0, 30" VerticalOptions="CenterAndExpand">
<Label
Text="{ext:Localizing CountryName}"
HorizontalOptions="CenterAndExpand"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Sample application demo
You can see that the text (CountryName) in the application is changed to the localized text when the language setting is changed.