Windows Develop Bookmark and Share   
 index > Windows Forms Designer > Localizing multiple forms using a single resource file
 

Localizing multiple forms using a single resource file

Hi!

I would like to use the localization feature of the VS form designer. When I localize a form, the designer creates a few resx files (one per language I think) and stores all the localization data in there. The designer creates one set of resource file per control as well. My problem is that my project has dozens of controls and forms, and the result is an unwieldly amount of resource files.My company has a specialized resource to translate text, but that resource is not a programmer, and using VS and form designers is out of the question for her.

One possible solution would be to scan all the resx files, compile a central repository file with all the localizable text, provide this file to the translator, then parse and reassign all localized text in the appropriate resx files. This seems tedious, and risky (playing with the resx file directly seems like asking for trouble).

I was wondering if there's a way to have the form designer use a single resx file for all text data.

Any other solution is welcome.

Thank you
Billy Bob Richert  Friday, July 17, 2009 7:30 PM

Hi Billy,

Yes, your understanding about the recommended way of localizing an application is correct.

Although we have to translate a same text a few dozen times and make a fix a few times once again if necessary later, the .resx or .resource files for each form and each culture is easy to manage and you needn't code by yourself to support localization in the application. On the contrary, if you centralize the localized text data for all forms for one culture in one .resx file, it will be difficult to manage the text data because you need to differentiate which text data is for which form and for which control and for which property. You also need to code by yourself to support localization in the application.

Hope this helps.


Please remember to mark the replies as answers if they help and unmark them if they provide no help. end us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Linda Liu  Thursday, July 30, 2009 2:55 AM
In this case, rather than using the forms Localizable property You could manually localize the forms.

You can then have all strings added to a single resx file (although I think that this would be confusing) and prefix all resource identifiers with the TwoLetterISOLanguageName (i.e. OKButton would have several entries such as enOKButton, deOKButton, esOKButton, frOKButton etc...).

You could then create a simple static class to extract the relevant resource from a central Resource File.

Here is a simple static class (may need refining for your specific needs) which uses the single resx file:
(assumes your resx file is called LocalizedStrings.resx and your project namespace is WindowsFormsApplication1

using System;
using System.Threading;
using System.Resources;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public static class StringLocalizationTool
    {

        public static void Localize(Control control)
        {
            String txt = GetLocalizedString(control.Name);
            control.Text = txt == "" ? control.Text : txt;
            if (control.Controls.Count > 0)
                Localize(control.Controls);
        }

        private static void Localize(System.Windows.Forms.Control.ControlCollection controls)
        {
            foreach (Control child in controls)
            {
                String txt = GetLocalizedString(child.Name);
                child.Text = txt == "" ? child.Text : txt;
                if (child.Controls.Count > 0)
                    Localize(child);
            }
        }

        private static String GetLocalizedString(string objectName)
        {
            String lang = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;
            ResourceManager resx = LocalizedStrings.ResourceManager;

            resx.IgnoreCase = true;

            return resx.GetObject(lang + objectName) == null ?
                string.Empty :
                resx.GetString(lang + objectName);

        }

    }
}



Now in your forms constructor you simply make the following call after the InitializeComponent() call:

StringLocalizationTool.Localize(this);

The preferable solution would be to have seperate language versions of the resx files (i.e. LocalizedStrings.resx, LocalizedStrings.de-DE.resx, LocalizedStrings.es-ES.resx, etc...). If you then decide to add a new language you simply copy an existing resx file and translate it. This way you are unlikely to miss an entry.

The above class would then need to have the GetLocalizedString() method modified as follows:

        private static String GetLocalizedString(string objectName)
        {
            ResourceManager resx = LocalizedStrings.ResourceManager;

            resx.IgnoreCase = true;

            return resx.GetObject(objectName) == null ?
                string.Empty :
                resx.GetString(objectName, Thread.CurrentThread.CurrentCulture);
        }

Mick Doherty
http://dotnetrix.co.uk
Mick Doherty  Sunday, July 19, 2009 12:42 PM
That is the solution I'm currently implementing (with a slight variation: I use the english text as key instead of control names, this allows me to reuse some translation values and makes corrections much easier). This solution however prevents me from using the form designer's feature for localization: namely the ability to change the position and size of all the controls between two languages at design time. This is a neat feature I wanted to use without implementing the whole thing myself.
Billy Bob Richert  Monday, July 20, 2009 12:51 PM
Actually there is something I wanted to ask you Mick regarding your solution:

In your design, if 2 controls have the same name, they will automatically have the same translation, which is not necessarily desired.

My point is, with the current implementation of localization, if I wanted to change the way "Hello World!" is translated, I would have to go through dozens of forms, and change the text every time it appears. This seems archaic and not very scalable at all. Is that really the solution that people use? I am surprised that VS does not offera way to centralize all text resources for all forms, since it seems like a pretty basic requirement for localizing any big software project. Why is it not so?
Billy Bob Richert  Monday, July 20, 2009 2:38 PM
My solution was not meant to be comprehensive, just a basic outline which should be modified to suit your requirements. Text would be a better option for the identifier in this case though.

I don't write applications and so have never had the need to use the Localizable property, but it does seem very limiting.

It's the forms CodeDomSerializer which is responsible for choosing whether to serialize to resource or to InstanceDescriptor so I doubt that you'll find any way to change the behaviour.

Another option you have is to use Settings files. You can add as manySettings files as needed and can store most property values in them. You'll still have to manually edit each file seperately, but you won't have to duplicate common settings. You would still need to cycle through all properties and assign them one at a time though, soI don't know if it's any better than the solution you already have.

It does seem a bit ridiculous that you can't assign different ApplicationSettingsBase files in one hit rather than having to assign each property individually. Perhaps this should be a new feature in VS2010 (maybe it is, I'll have to boot to Windows7 and check ;) ). It would be great to able to completely change the entire application layout with a single settings base swap (especially at design time) and this would definately benefit programmers writing multiligual apps, or even apps with different view modes such as basic and complex or compact and normal. The more I think about it, the more useful it becomes.
Mick Doherty
http://dotnetrix.co.uk
Mick Doherty  Monday, July 20, 2009 9:59 PM

What canI do to bring this thread to the attention of the VS team? It seems like a valid suggestion.

Thanks for your time Mick.

Billy Bob Richert  Tuesday, July 21, 2009 12:57 PM
Hi Billy,

The recommended solution to localize an application is to build the application with Visual Studio and then use Windows Forms Resource Editor(Winres.exe) to generate localized resource files and bundle these resource files into satellite assemblies. You need to createa satellite assembly for each culture the application supports. Note that you should bundle all resource files of the same culture into one satellite.

Please read the following MSDN documents for more information:
"Resources in Applications"
http://msdn.microsoft.com/en-us/library/f45fce5x.aspx

"Packing and Deloying Resources"
http://msdn.microsoft.com/en-us/library/sb6a8618.aspx

"Windows Forms Resource Editor(Winres.exe)"
http://msdn.microsoft.com/en-us/library/8bxdx003(VS.80).aspx

"Creating Satellite Assemblies"
http://msdn.microsoft.com/en-us/library/21a15yht(VS.71).aspx

Hope this helps.
Please remember to mark the replies as answers if they help and unmark them if they provide no help. end us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Linda Liu  Tuesday, July 28, 2009 9:49 AM
I've glanced over those links Linda, and it does not help me with my problem.

What the VS localization tool (and apparently the winres.exe tool) cannot do is centralize the text data. For example,let's say I have a "Hello World!" label in a few dozen forms. Using the localization tools you offer, I would have to translate that same text a few dozen times.

If we should one day decide to use a slightly different sentence for a particular translation, we would have to make that fix a few dozen times once again. This is not acceptable.

My problem is not so much that I have many resx files, like my original post may imply. My problem is that I have to do a whole lot of copy pasting using this technique.

I'm not sure I'm being clear on my problem, please feel free to ask for clarifications. Your help is very appreciated.
Billy Bob Richert  Wednesday, July 29, 2009 1:05 PM

Hi Billy,

Yes, your understanding about the recommended way of localizing an application is correct.

Although we have to translate a same text a few dozen times and make a fix a few times once again if necessary later, the .resx or .resource files for each form and each culture is easy to manage and you needn't code by yourself to support localization in the application. On the contrary, if you centralize the localized text data for all forms for one culture in one .resx file, it will be difficult to manage the text data because you need to differentiate which text data is for which form and for which control and for which property. You also need to code by yourself to support localization in the application.

Hope this helps.


Please remember to mark the replies as answers if they help and unmark them if they provide no help. end us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Linda Liu  Thursday, July 30, 2009 2:55 AM
Well I find that it would be much easier to centralize text. I don't care where any particular text appears, I just want to normalize it. If I want my "Hello World!" to become "Hello Everyone!" I want to have to change it only once, and never have to worry about some forgotten label in the dark corners of my app.

What you're telling me is that VS localization does not support this.

Very well, I'll have to do it myself.

Thank you for your help.
Billy Bob Richert  Thursday, July 30, 2009 1:09 PM
Hello all,

Our solution is similar like the one of Linda. Maybe it helps you to find a good way:

We develop our application in Default Language (english) and one user specific language (german) in Visual studio and set all Forms to Localizable=true.

After the Build-Process we send the application with german satellite assembly to our documentation department. With this all recources are packed in the application and in one satellite assembly. The documentation department uses a professional tool which exctracts all texts from the assemblies and add these texts into a database. These text fragments will be synchronized with a table containing texts which are already translated. This makes sense, because a text will be translated only once. The texts which have to be translated will exported with an excel and after the translation process imported into the database. Afterward the documentation department generates us a satellite assembly which we can deliver with our application.

This way makes sense, because we are several development team which are working completely independtly. We have the guarantee that a text will be translated only once. With this solution we could reduce the translation costs and the developers can focus their time for developing working functions and not invest time for translation applications!

best regards,
Peter
phue  Friday, October 02, 2009 9:04 AM
That sounds exactly like what I need phue. What is the name of the professional tool you use to centralize your localization data?
Billy Bob Richert  Friday, October 02, 2009 1:19 PM

You can use google to search for other answers

Custom Search

More Threads

• How to put a pop-up box control into Toolbox?
• What's wrong with the designer ?
• Newbie Question
• [solved] Display a designer form in an external application without freezing external application events
• Visual inheritance, Design Error
• Change TextBox drawing rectangle
• Remove the icon from the system tray programmatically
• UserControl share instance
• Any Ideas - CodeDomSerializer, InitalizeComponet and ResourceManager
• Designer keeps adding tablestyles in VS 2003.