Click here to Skip to main content
15,883,901 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello,

I am trying to craete wpf application with multi language. First I created 2 resource dictionaries the first is english and the second is spansih. The have the following structure:

english.xaml
HTML
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:system="clr-namespace:System;assembly=mscorlib">

    <system:String x:Key="UserID">User ID</system:String>
    <system:String x:Key="UserPassword">User Password</system:String>
    <system:String x:Key="Login">Login</system:String>

</ResourceDictionary>


spanish.xaml
HTML
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:system="clr-namespace:System;assembly=mscorlib">

    <system:String x:Key="UserID">ID de usuario</system:String>
    <system:String x:Key="UserPassword">usuario Contraseña</system:String>
    <system:String x:Key="Login">Iniciar Sesión</system:String>

</ResourceDictionary>


In MainWindow.xaml.cs
C#
string language = "english";

public MainWindow()
        {
            InitializeComponent();
            SetLanguageDictionary();
        }

private void SetLanguageDictionary()
        {
                ResourceDictionary dict = new ResourceDictionary();
                switch (language)
                { 
                     case "english":
                     dict.Source = new Uri("Resources/english.xaml",UriKind.Relative);
                     break;

                     case "spanish":
                     dict.Source = new Uri("Resources/spanish.xaml",UriKind.Relative);
                     break;

                     default :
                     dict.Source = new Uri("Resources/english.xaml",UriKind.Relative);
                     break;
                }
                this.Resources.MergedDictionaries.Add(dict);
        } 



In App.XAML

HTML
<Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/english.xaml" />
                <ResourceDictionary Source="Resources/spanish.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>


and In my form I do the following for each label
HTML
<Label Margin="5" Content="{DynamicResource UserID}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="274"/>


The problem now that I get only spanish translation even if I change the language to english.
Posted
Updated 19-Mar-15 4:34am
v2
Comments
TheRealSteveJudge 19-Mar-15 10:44am    
I just tried your solution and it shows the label
in the language defined by "language".
The problem cannot be reproduced.

To start with, you are doing wrong thing: "manual" localization, while .NET in general and WPF in particular suggest much more robust, reliable and "automated" way of globalization and localization based on satellite assemblies. You can start here: https://msdn.microsoft.com/en-us/library/ms788718%28v=vs.110%29.aspx[^].

One particular bad thing you are doing is is hard-coding immediate constants like "english", "spanish", etc. This is not supportable. It's apparent that, with such approach, you have to write such string at least twice. If you misspell, the compiler will never warn you.

Not only your approach is "manual" and self-baked, it's just very bad, especially when compared with real .NET globalization/localization. You can switch culture even during run-time, and, in certain cases, specify "wrong" culture, which is not exactly implemented in the set of localizations. Then the fallback mechanism will always get you some UI (and non-UI resources), closest to what you wanted. For example, if you want "en-GB" which is missing, you can get "en".

This is the table of culture codes: https://msdn.microsoft.com/en-us/library/ee825488%28v=cs.20%29.aspx[^].

I always try to encourage people, including myself, to "reinvent the wheel", but you need to check your invention by comparing it with known approaches which may or may not appear to be better than yours. For this purpose, you really need to read documentation and other source, not only write code…

—SA
 
Share this answer
 
Remove the merged dictionaries from App.xaml.

Currently, you have both dictionaries merged, with the Spanish version merged last. As a result, the Spanish resources will always replace the English resources.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 19-Mar-15 11:20am    
Can you see that the general approach of the inquirer is bad, home-baked, hard-coded..? It just does not worth fixing, in your way or any other, because really good civilized .NET globalization/localization techniques are readily available.
Please see my Solution 2.
—SA
Hassan Dbouk 19-Mar-15 15:28pm    
Thanks SA, Richard what other way to do, without merged dictionaries?
Richard Deeming 19-Mar-15 15:33pm    
If you're sticking with your approach, then you need to take the merged dictionaries out of App.xaml, and only add the required dictionary from the App.xaml.cs or MainWindow.xaml.cs file. Currently, you have both dictionaries merged in all the time, with the Spanish version "winning" as it was the last to be added. Adding the English dictionary again has no effect.

However, SA is right; there are much better ways to do this.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900