my Team Project (UWP App in C#) is offered in two languages (de-DE and en-US).
The project has a Resources.resw file stored in
"Model\DataManager\ResourcesManager\Language\de-DE\"
which contains all the strings that related to the GUI.
For my part i need to handle specific tasks differently based on the language of the App, but the problem is, neither me nor my team knows how to really work with the resourceloader.
I have the following problems:
1) I was told that the resourceloader gets automatically the windows language and use it in the app if it is available, otherwise App default will be used.
What i was also told is that this cannot be changed internally, even if the user wants that (like in the settings page or so) and the only solution is to change the windows language. is this true? if not how can it be done?
2) For my part i need to know the current language of the App but i don't know how and i also need to store the language related strings in an appropriate resources file.
I tried to define a new file named LPResources.resw where i added all the strings like:
DBQueryGenerator_DateInterpreter_month-12 means December in the English version.
But trying to access this string with:
ResourceLoader resources = new ResourceLoader("LPResources");
or
ResourceLoader resources = ResourceLoader.GetForCurrentView("LPResources");
and then
resources.GetString("DBQueryGenerator_DateInterpreter_month-01")
throws directly an exception ResourceMap Not Found.
I tried to search for a solution but i couldn't find any helpful information.
If you can answer one of the questions or both i would really appreciate it.
1) I was told that the resourceloader gets automatically the windows language and use it in the app if it is available, otherwise App default will be used. What i was also told is that this cannot be changed internally, even if the user wants that (like in the settings page or so) and the only solution is to change the windows language. is this true? if not how can it be done?
This is not very accurate. The resources that Windows loads for your app and also the language(s) used to format dates, times, numbers, and other components are determined by the app runtime language list and it is made up of these items:
(Optional) Primary Language Override.
The user's languages that are supported by the app.
If 1 and 2 are empty, then the default or first language supported by the app.
The detailed information is introduced in this document: Understand user profile languages and app manifest languages.
2) For my part i need to know the current language of the App but i don't know how and i also need to store the language related strings in an appropriate resources file. I tried to define a new file named LPResources.resw.
As the reply above, to get the current language, you should get the app runtime language list, you can get it use the following three ways.
//First way
string runtimeLanguages = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().QualifierValues["Language"];
//Second way
IReadOnlyList<string> runtimeLanguages1 = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Languages;
//Third way
var runtimeLanguages2 = Windows.Globalization.ApplicationLanguages.Languages;
Then you can make a simple judgement to get the what the user sees in the app. (Of course, you should read and understand the Understand user profile languages and app manifest languages document firstly.)
For getting the resource, I tried the code,
var Loader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView("LPResources");
var text1 = Loader.GetString("DBQueryGenerator_DateInterpreter_month-12");
It can return the defined text value, please check you resource file name and make sure it is correct.
Note: "LPResources" is the LPResources.resw file, and "DBQueryGenerator_DateInterpreter_month-12" is the resource string Name.
You can also use the following code to get the resource,
ResourceMap resourceMap = ResourceManager.Current.MainResourceMap.GetSubtree("LPResources");
ResourceContext resourceContext = ResourceContext.GetForCurrentView();
var str = resourceMap.GetValue("DBQueryGenerator_DateInterpreter_month-12", resourceContext).ValueAsString;
Note that: Whether the LPResources.resw file is in the project's root directory or in a folder of the project, you can call it using its name directly.
Related
My app has been designed to be able to run on two different languages, english and czech. In order to accomplish this, I've created 2 resource files:
If an end-user would like to add another language, for example GlobalStrings.fr-FR.resx, is it possible to allow for this functionality without rebuilding the application?
If we look at the properties of these resource files:
I'm not understanding what embedded resource means. Does this mean that in order for the app to consume this file, the application must be rebuilt?
How do we create a resource file, that is open to be extended/changed by the end user, without having to rebuild the entire application
?
Regular .Net resources are compiled into assembly with particular name and loaded by matching that name. So if "end-user" is ok to translate strings in resx file and compile resources into assembly with particular name (like "MyResources.cs-cz.dll") you can do that with default .Net behavior without recompiling main code. See MSDN:Packing and Deploying resources and related links for more information.
Note that you don't need Visual Studio for it and can use csc command line compiler to embed resources on user's machine - so if your really want you can provide simple script that compiles corresponding resx locally. Note that editing XML (resx) as text is generally not possible by regular person due to required encoding of some characters - consider technical level of your "end-users" before going that route. Plain text version of source for resource may work in more cases.
Usually this is not the case - if end-user localization is requirement you would create some sort of custom resource string management by loading strings from plain text files or database that users can update locally.
Im goind through the bot framwork and Im having trouble fixing the global language.
The problem is that I cannot change the backend commands and responses that are built in the framework, they are always in english.
For example, in Formflow, I would like to enter "help" but in other language instead.
Or whenever a question in a QnAbot is not found, I would like the defaul "...Is not a valid query" to be in another lenguage instead
Are different languages built in or do I need to code every commmand translation?
If you’d like to implement localization, you can try to create resource files for language that you want and add&use it in your project. When a form is created, the IFormBuilder.Build method will automatically look for resources that contain your form type name and use them to localize the static strings in your form.
This article describes Localize form content, please refer to it. And you can find these main steps:
Generate a resource file, you can either use IFormBuilder.SaveResources or use the RView tool
After generated a resource file, add it to project and then set the neutral language withe these steps:
Right-click on your project and select Application.
Click Assembly Information.
Select the Neutral Language value that corresponds to the language in which you developed your bot.
After added resource files to project, use the Multilingual App Toolkit (MAT) to localize them.
you can try it by using
var english = new Option();
english.Locale = "en-US";
Reference: GitHub
I'm looking for the best way to create a multi language application. I want to have the language files in a external Class Library so it's reusable for multiple applications so I only have to add it to the References (and probably some code in the .xaml itself).
EDIT 1: With multi language I mean like Dutch, English, German, ...
The goal is to have the computer system to say, if it's in Dutch, the application has to be Dutch, but if it's in French, it takes English as default. This should be done in a dll, so it's not "hard coded" in each application I make.
EDIT 2:
I managed to solve this problem on my own. Thanx to the people who replied to my problem.
I solved it this way:
I made a Class Library and named it "Languages". I added 2 Resources named "Language.nl-BE.resx" and Language.en-US.resx" with both a String in the file named "exDefault". After that I compiled it and added the dll as a Reference to my application.
In the application I used the following code to get the String into my application:
ResourceManager rm = new ResourceManager("Languages.Language", System.Reflection.Assembly.LoadFrom("Languages.dll"));
MessageBox.Show(rm.GetString("exDefault", new System.Globalization.CultureInfo("en-US")));
This will get the content of the "exDefault" String in the en-US source and show it in a MessageBox. To show the other language, just change en-US to nl-BE.
You will notice there is a dll named Languages.dll and 2 folders named en-US and nl-BE with each their own Languages.resources.dll file inside them.
The only thing I'm wondering now is, is there a way to get rid of those 2 folders and embed them inside the Languages.dll?
You might want to read the sections on globalization / localization in the WPF and .Net documentation. Also, you might want to check out this blog, where there are examples of how to use localized resource dlls in WPF:
http://wpfglue.wordpress.com/category/localization/
I managed to solve this problem on my own. Thanx to the people who replied to my problem.
I solved it this way:
I made a Class Library and named it "Languages". I added 2 Resources named "Language.nl-BE.resx" and Language.en-US.resx" with both a String in the file named "exDefault". After that I compiled it and added the dll as a Reference to my application.
In the application I used the following code to get the String into my application:
ResourceManager rm = new ResourceManager("Languages.Language", System.Reflection.Assembly.LoadFrom("Languages.dll"));
MessageBox.Show(rm.GetString("exDefault", new System.Globalization.CultureInfo("en-US")));
This will get the content of the "exDefault" String in the en-US source and show it in a MessageBox. To show the other language, just change en-US to nl-BE.
You will notice there is a dll named Languages.dll and 2 folders named en-US and nl-BE with each their own Languages.resources.dll file inside them.
The only thing I'm wondering now is, is there a way to get rid of those 2 folders and embed them inside the Languages.dll?
I have a WinForms application which I want to translate into multiple languages. However, I do not have any experience with localizing a WinForms app, and I find very contradictory information about this subject.
Basically, what I want is:
In the source code, I want only one file per language
This file gets compiled into the main application on compilation - no satellite assemblies or external data files after building the application
The user can select the language, I do not need/want auto-detection based on the operating system
This should mainly contain strings and ints, but also a CultureInfo
Most solutions I've seen either have one .resx file per Form and/or external satellite assemblies.
Do I have to roll my own?
Or is there something in the framework already?
.net Framework 3.5 SP1 if that matters.
Edit:
For the most part, Visual Studio already offers support for what I want, but there are two issues. When I set Form.Localizable to true I have this nice Designer support, but this generates one resx per Form. The idea of manually overriding it in InitializeComponent fails because it's designer-written code that will regularly be overwritten.
Theoretically, I only want to :
a) override the creation of the ComponentResourceManager to point it to my global resx and
b) change the call to ApplyResources to the overload that takes a CultureInfo as third parameter.
It seems as if I have to add a function call to my constructor that gets called after InitializeComponent() and overrides its behaviour. That seems terribly inefficient, but Visual Studio is right when it warns about touching InitializeComponent().
At the moment, I am indeed rolling my own WinForms localization Framework...
I've just completed a C# .Net 3.5 project with a similar problem. We were writing WinForms plugin for an existing multi-lingual application with 8 languages (including English).
This is how we did it:
Create all our forms and UI in the default language, English.
Put all our internal strings in a resource file (stuff not tied directly to a form like custom error messages and dialog box titles etc)
Once we had completed most of the work and testing we localised it.
Each form already had a .resx file but this was empty. We set the property 'Localizable' to true, the .resx file was filled with things like button sizes & strings.
For each of the other languages, we changed the 'Language' property on the form. We chose the basic version of each language eg: 'Spanish' instead of 'Spanish (Chile)' etc. so that it would work for every 'Spanish' dialect, I think.
Then we went through each control, translated its text and resized, if needed. This created a .resx per language and form combination.
We were then left with, for 8 languages, 8 .resx for each form and 8 .resx for the general strings. When compiled the output folder had the .dll we were creating and then a sub folder for each language with a .resources.dll in it.
We were able to test the versions of the UI in the designer by just changing the language property to check that we had the correct strings & layout.
All in all once we got our heads around it, it was quite easy and painless.
We didn't need to write any custom tweaks to the form loading
I was asking a similar question about ASP.NET and got a first answer - this tool and its workflow might also be something for you - have a look: Lingobit Localizer
It seems to be able to load your Winforms app and allows you to start translating your labels etc. and see the forms while you do it. Lots of other features, too, like incremental translation and translation memory (if you use the same terms over and over again).
Looks quite promising (for Winforms) - haven't used it myself, though.
Here's an extensive list of potential .NET localization tools - not sure, how well they work and what they cover - have a look, maybe you'll find what you're looking for.
Marc
I dont have a solution for your first and second requirement but keep in mind that localizing a form is not as simple as translating each word. You need to check that each translated text fits in their respective control. Also, maybe you have an icon or an image which need to be change in another culture.
For your point three, you can change the language manually with the following lines:
CultureInfo ci = new CultureInfo("fr");
Thread.CurrentThread.CurrentUICulture = ci;
This is a huge subject and there are many ways to accomplish what you want. The framework does provide the basis but a complete solution requires that you implement certain elements yourself.
For example the default framework implementation is to create a .resx file for every resource. In ASP.Net this means each user/server control or page. This doesn't lend itself to easy maintenance and if you want to move resources to a database you need to implement your own provider.
My familiarity with Winforms is limited but if you are using Silverlight or WPF then have a read of Guy Smith-Ferrier's work on the subject at: http://www.guysmithferrier.com/category/Internationalization.aspx. He also has some toolsets that can make your life easier at: http://www.dotneti18n.com/Downloads.aspx.
I've worked with him before and have never come across anyone else with a better depth of understanding of the subject.
What you are asking for:
no satellite resource files
only one size and control placement per form.
lots of languages embedded in the executable.
Is not do-able in vanilla Visual Studio's IDE.
What it would require is some custom work, basically fulfilling all these steps:
Acquire a custom resource manager that handles TMX resource files.
Put all your localizable strings in a TMX file.
Make this TMX file an embedded resource in your project.
In your Form constructor, create your TMX ResourceManager, loading the TMX file from your embedded resources.
In your code, use your tmx ResourceManager instead of the default ResourceManager for getting localized strings.
Let the Form use the default ResourceManager for getting all the designer things except the strings.
Get your TMX file fleshed out with the new language translations.
More can be added in the next release of your project, just by adding them to this TMX file before you compile.
RESOURCES: (not an exhaustive list, by any means)
http://en.wikipedia.org/wiki/Translation_Memory_eXchange
http://sourceforge.net/projects/tmx-editor/
The right way to do this is, suppose you want to add Arabic support witch is RightToLeft language:
Double click the form
Set localizable prop. to true
Change Language prop. to Arabic //This will automatically open a new version of the form so you can customize.
Set RightToLeft prop. to Yes
Set RightToLeftLayout prop. to True
Start renaming controls, and save the form.
Handle Messages/Errors in code // Sorry I don't have a quick solution for now, try duplicate them and If/Else the current local.
We have a resource file with lots of translated strings used various places in our application. Is there a better way for binding for example the text of a button to a certain string?
Currently we are usually just doing something like this in the constructor, in a Load event handler or in a method called by one of those:
someButton.Text = CommonTexts.SomeString;
someMenuItem.Text = CommonTexts.SomeOtherString;
Is there a better way to do it? Maybe in the designer? Or is this the recommended way of doing it?
Just to let you know how we do the actual translation: We have one Class Library project which only contains resx files. The main resx files are written in english (of course). We then open up those base resx files in an application called ResEx where we (or someone else) does the translation to other languages. When compiled Visual Studio automatically creates assemblies for each language which are used automatically depending on the current culture set. This works pretty well, so I don't really need info on how to do the translation and such (although I am always curious to improvements of course). What I am asking is if there is a better way for getting those translated strings from the resource assembly and into all the various Text properties.
I understand, it's an old question, but still, I had the same issue (VS 2010), and one of the first links in google is this topic.
In order to move all the texts to forms resource file - you need to set the winform Localizable property to True. And that's it. :)
(c) Cap. O.
You can do:
using System.Resources;
using System.Reflection;
Assembly assembly = this.GetType().Assembly;
resman = new ResourceManager("StringResources.Strings", assembly);
btnButton.Text = resman.GetString("ButtonName");
There is a good tool called LingoBit Localizer that does the job for the fraction of the time it would take to build all the reasources files.
You don't have to care about other languages while in development process, you simply code and set properties as you would if you were programming for a unilingual software. After you're done, or whenever you wish, you run LingoBit Localizer over your DLL or Windows Form application. This will get user-displayable strings out to a grid for you within its GUI. Now, perhaps a professional translator could use to translate the words if your programmers don't know the language for which the applicaiton have to be translated. Then, you simply save the project when you're done. This will create a DLL file which you simply add to your binary deployment directory, then your application will automatically set itself to the right language depending on the current culture information on which the app. is installed or so. This saves a lot of programming time and headaches.
Hope this helps even though it is not resource-based solution.
This will extract the the value of Home keyword and populate into the Text1 Box.
Text1.Text= Resource.Home.ToString();
Try this:
someButton.DataBindings.Add("Text", CommonTexts, "SomeString");
Your way is the best way to do this if you have developers who are not personally fluent in the languages you're translating your application into. I've done this before with an English application that had to be translated into Spanish, Portuguese and Chinese (I only speak one of these semi-fluently). The original forms were all created in English, and in the form's Load event the code iterated through every control and searched for each control's Text property in a translations spreadsheet, and replaced it with the appropriate translation.
The built-in way of internationalizing a form (which is basically a variant of form inheritance) assumes that the programmer is fluent in the language you need to translate to, which is pretty much of a stretch, and it requires you to manually enter all the translated text values for each form and each language. It also makes your binary larger (potentially much larger), since it adds a .resx file for each form for each language that you support.