سؤال

I have a couple of issues with windows store app localization. I am able to localize xaml stuff like TextBlock.Text or Button.Content(I'm doing it in the same way as shown here), but I have no idea how can I localize following things:

1). Items in my ComboBox.

<ComboBox x:Name="comboBoxTopAppBar" Width="120" Margin="10,0,0,0" MinWidth="200"
                      SelectedItem="{Binding SelectedStatus, Mode=TwoWay}">                   
                <x:String>Item 1</x:String>
                <x:String>Item 2</x:String>
                <x:String>Item 3</x:String>                   
            </ComboBox>

2). MessageDialogs in C# code(without await because of catch block)

new MessageDialog("Something went wrong. Please, check your login/password and internet connection.").ShowAsync();

3). Toast notifications in C# code(I am using class library from "Windows Runtime via C#" book)

ToastNotificationManager.CreateToastNotifier()
                        .Show(new ToastNotification(new ToastTemplate(ToastTemplateType.ToastText01)
                        {
                            Text = {"Fetching your data. Please, wait."},
                            Duration = ToastDuration.Short,
                        }));

How can I localize it?

هل كانت مفيدة؟

المحلول

Interestingly, they all tie together.

For 2) and 3) you need to create a Controller which will hold a ResourceLoader object. You can use (if using Windows 8.1), ResourceLoader.GetForIndependentUse().

Create a method in your ResourceController called GetTranslation(string resource). It will look something like this:

private static ResourceLoader resourceLoader = ResourceLoader.GetForIndependentUse();

public static string GetTranslation(string resource)
{
    return resourceLoader.GetString(resource);
}

Then, whenever you need a static, coded translation, just call ResourceController.GetString(*key of the string you want*).

This works great for simple code calls, but doesn't work directly for Xaml, such as your scenario 1). Fear not though, as you have the magic of Converters!

public class ResourceTranslationConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var valString = value as string;

        // If what is being converted is a string, return the resource translation
        // Else return something else, such as the object itself
        return valString == null ? value : ResourceController.GetString(valString);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Then, all you have to do is define the converter once (likely somewhere accessible from all of your xaml, possibly a dictionary merged into your App.xaml) and you can refer to it in a binding whenever you want!

For this instance, something like:

<!-- This is defined somewhere accessible, or just in the Page Resources -->
<!-- 'converters' is whichever namespace definition your converter is in -->
<converters:ResourceTranslationConverter x:Key="ResourceTranslationConverter"/>

<ComboBox x:Name="comboBoxTopAppBar" Width="120" Margin="10,0,0,0" MinWidth="200"
          SelectedItem="{Binding SelectedStatus, Mode=TwoWay}">    
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource ResourceTranslationConverter}}"
        </DataTemplate>
    <ComboBox.ItemTemplate>

    <x:String>Item 1</x:String>
    <x:String>Item 2</x:String>
    <x:String>Item 3</x:String>                   
</ComboBox>

This way all your text is being passed through your ResourceLoader at runtime and automatically. Any new Items you define will also be automatically translated (so long as they have an entry in your Resources and are translated).

Hope this helps and happy coding!

نصائح أخرى

I want to post an alternative to question (1) localize items in ComboBox with C# code. It is more straight forward:

xaml

<ComboBox x:Name="comboBoxTopAppBar"/>

C#

var loader = ResourceLoader.GetForCurrentView();
comboBoxTopAppBar.Items.Add(loader.GetString("kItem1"));
comboBoxTopAppBar.Items.Add(loader.GetString("kItem2"));
comboBoxTopAppBar.Items.Add(loader.GetString("kItem3"));
comboBoxTopAppBar.SelectedIndex = 0; 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top