I try to make my application multilingual. For this I have created two resource files:
Resource.de-DE.resx
Resource.en-US.resx
Both are set to public and contain the same keyword and translation. I can also access the keywords in the backend -> see image.
Unfortunately my program does not load the files when I change the language.
My steps:
set the default Resources.resx to public.
copied this file twice
renamed file to (see above)
keywords+translation entered and checked
project created again
included on the Button-Content by:
<Button x:Name="Home_Button" Style="{DynamicResource Menuebutton}" Content="{x:Static p:Resources.Menue_home}" Click="Home_Click"/>
access of the object set by:
xmlns:p="clr-namespace:VS_Launcher.Properties"
include in the MainWindow.xaml.cs by:
CultureInfo myCultureInfo = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = myCultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = myCultureInfo;
Thread.CurrentThread.CurrentCulture = myCultureInfo;
Thread.CurrentThread.CurrentUICulture = myCultureInfo;
In another project I did the same thing. But there the solution worked. What is my error?
Resource Files
Directory structure
Are you sure the file names of alternative language resources (excluding culture-locale) are identical with default one? If the default one is Resources.resx, alternative ones must be like:
Resources.de-DE.resx
Resources.en-US.resx
Related
I'm trying to localize my app, I've created several Resources.[culture].resx but program ignores them all and always loads default Resources.resx.
I have this code in App construtor (and in OnStartup event)
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
My resources are called Resources.en-US.resx, Resources.cs-CZ.resx and Resources.resx
Code in WPF is
xmlns:p="clr-namespace:WpfThermalLabelEditorApp.Properties"
Title="{x:Static p:Resources.Title}"
This should load en-US localization but it doesn't. Loads default. I tried to delete AssemblyInfo and even putting <UICulture> tags into csproj
Not sure if this is the answer, but FWIW: I always set both CurrentCulture and CurrentUICulture like so;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(languageAbbreviation);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(languageAbbreviation);
And be sure to double check the abbreviation you use is the same for all references. That should fix your problem.
EDIT1: Make sure your resource files are set to public, the access modifier should be somewhere near the top when you're viewing the resource file. Double check this says public and rebuild. Also, to call your resource file key do so like this:
<TextBlock xmlns:local="clr-namespace:WpfApplication2" Text="{x:Static local:Resource1.myname}"/>
Where...
"WpfApplication2" is replaced with your project name
"Resource1" is replace with the name of your resource file (without culture id, e.g. for your case it would just be Resources)
"myname" is replaced with the key you want
I came across the same problem, the solution was to clean and rebuild the project. No need to create new project.
Well, after 2 days I've solved my problem. My solution was correct. I have no idea what was wrong but I've created a new project, moved all my data to a new one and suddenly everything worked as a charm.
Here is a few usefull links:
WPF localization and globalization
Localization tutorial
Localization tutorial 2
Problem
I am trying to implement a system in my program to switch language. I found out that i can use CultureInfo and ResourceManager to achieve that. I built up this code after a couple of hours having problem with the resource not found, finally i found and answer here on stackoverflow and i arranged the following code:
CultureInfo culture;
culture = CultureInfo.CreateSpecificCulture("it-IT");
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
Assembly resourceAssembly = Assembly.Load("MY ASSEMBLY NAME");
ResourceManager manager = Properties.Resources.ResourceManager;
string[] manifests = resourceAssembly.GetManifestResourceNames();
string manifest = manifests[0].Replace(".resources", string.Empty);
manager = new ResourceManager(manifest, resourceAssembly);
string greeting = String.Format("The current culture is {0}.\n{1}",
Thread.CurrentThread.CurrentUICulture.Name,
manager.GetString("HelloString"));
MessageBox.Show(greeting);
Since this is a really big program with a lot of pages, windows and usercontrols, i need to access the language from a lot of different files.
The code i posted above, should look into the root of my Solution and look for a file named it-IT.resx. it says that the current culture is it-IT but it doesn't write the value of HelloString, but it doesn't give any error so it's definitely a problem with Resource Manager but i don't know why it doesn't crash saying it doesn't find the resource. I am sure that inside the resx file there is a value called HelloString.
Is there a reason to load the types dynamically with Assembly.Load()? It is asking for trouble. Another way would be adding a static assembly reference.
This approach has many advantages:
the resource names can be accesses as property names, it is comfortable
the calling code uses always existing resources
in the calling code there are no references to non-existing resources
To be able to use resources from another assembly the resource access modifier needs to be set to public:
If the resources file is named RText, as in the example above, the value of a resource can retrieved from another project with:
var val = ProjectWithResourcesNamespace.RText.HelloString;
I am having issues with the already mentioned NuGet package. I have created a folder named Resources, where I have inserted the following files:
Strings.en.resx
Strings.sk.resx (my default language)
I am using Prism, where my MainWindow (plain container) is located under root window and all the other pages are located under Views folder.
I have added the following to my MainPage view:
xmlns:lex="http://wpflocalizeextension.codeplex.com"
lex:LocalizeDictionary.DesignCulture="en"
lex:LocalizeDictionary.OutputMissingKeys="True"
lex:ResxLocalizationProvider.DefaultAssembly="eManagement"
lex:ResxLocalizationProvider.DefaultDictionary="Strings"
and here is an example of a TextBlock:
<TextBlock Text="{lex:Loc Key=Greetings}"/>
The problem is, that if I place the Strings.resx file in the root folder, the control is translated without a problem. But when I want to keep my translations under a Resources folder (meaning that english translation will be under Resources/Strings.en.resx), it suddenly does not work.
What do I need to change in order to make it work?
I was missing the following line:
lex:InheritingResxLocalizationProvider.DefaultDictionary="Strings"
Plus in the code-behind I had to manually set the culture as otherwise my culture was always invariant
#region Language Selection
var culture = new CultureInfo(Properties.Settings.Default.LanguageSettings);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.Culture = Thread.CurrentThread.CurrentCulture;
#endregion
This has solved the problem.
Trying to access a specific localised resource file such as WebResource.en.us which is located in my App_GlobalResources folder using the following code:
string resData = GetGlobalResourceObject("WebResource.en.us", "SomeResource").ToString();
but this keeps giving me the error below:
Could not find any resources appropriate for the specified culture or
the neutral culture. Make sure "Resources.WebResource.en-us.resources"
was correctly embedded or linked into assembly
"App_GlobalResources.bpqqrnv4" at compile time.
Any ideas ?
I tried the following Code
Page_Load(....)
{
/// note - i did NOT mention the culture when accesing my resourceFiles
Debug.WriteLineIf(
GetGlobalResourceObject("WebResource", "someResource")!=null,
GetGlobalResourceObject("WebResource", "someResource").ToString());
/// accessing a culture specific resource without changing Page Culture
CultureInfo yourCI = new CultureInfo("en-US");
Debug.WriteLine(
HttpContext.GetGlobalResourceObject(
"WebResource",
"someResource",
yourCI).ToString());
}
my Page directive
<% Page Culture="en-US" UICulture="en-US" ..... %>
My App_GlobalResources folder contains two files
WebResource.resx
WebResource.en-US.resx
Using this settings and code - my Debugger printed the value without any problems.
When removing WebResource.resx (my default ressource file) the same code throws an exception.
I would assume that you have to add a default resx file and remove the explicit culture notation in GetGlobalResourceObject(..., ..).
update: added some code to access specific resx culture file
see also MSDN
I have created some resource files to hold strings. I am displaying a MessageBox by pointing it directly at a resource file named TestLocalResource and a resource string named ThisIsMyTest by simply referencing the resource string like this:
TestLocalResource.ThisIsMyTest
Now this does appear to work. But this leaves me wondering that by referencing the resource string this way, will I always be accessing the default resource file (e.g., TestLocalResource.resx) rather than its German version (e.g., TestLocalResource.de-DE.resx)?
So instead, do I have to use ResourceManager? If so, how does ResourceManager know the current language (culture)? Will I need to explicitly set it?
This is how I think I would need to use ResourceManager:
ResourceManager resmgr =
new ResourceManager("MyApplication.MyResource", Assembly.GetExecutingAssembly());
But I'm hoping that there is a way to access localized resource strings in a more convenient fashion.
You don't need to use the ResourceManager explicitly.
Have a look here: http://geekswithblogs.net/mapfel/archive/2008/11/01/126465.aspx
To learn how to change the culture to use during runtime, see the second comment in the link:
switch (comboBox1.Text)
{
case "neutral":
Thread.CurrentThread.CurrentUICulture = new CultureInfo("");
break;
case "en-GB":
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");
break;
case "de-DE":
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");
break;
}
string messageText = Messages.MsgSampleText;
MessageBox.Show(messageText);
In the article referenced by #Daniel Hilgarth in his answer, the author indicates that the resource files named Messages.resx and Images.resx should each be created in the Properties folder. (The Properties folder is also the location where Visual Studio places its general-purpose resource file named Resources.resx.)
I found that Visual Studio 2013 would not allow me to create and place Messages.resx in the Properties folder by right-clicking the Properties node in Solution Explorer. Instead, here's what I did:
In Solution Explorer, right-click the Project node.
Select Add => New Item... => Resources File => Messages.resx. Result: Visual Studio places Messages.resx in the Project folder.
In Solution Explorer, drag Messages.resx to the Properties node.
As #Daniel indicates, a new class named Messages will now conveniently provide you with access to your resource strings. Note that Messages will be accessible via the YourProject.Properties namespace (where YourProject is the name of your project as shown in Solution Explorer).
For example, let's say that you have a resource string named OperationSucceeded. You will now be able to access that resource string via:
MessageBox.Show(YourProject.Properties.Messages.OperationSucceeded);
...or, more conveniently:
using YourProject.Properties;
MessageBox.Show(Messages.OperationSucceeded);