Click here to Skip to main content
16,016,306 members
Articles / Programming Languages / C# 4.0

ResToCode – Localization tool for Windows Desktop/Store/Phone applications

Rate me:
Please Sign up or sign in to vote.
4.87/5 (5 votes)
16 Mar 2014CPOL7 min read 10.8K   151   10   2
ResToCode converts resource files to a class that could be used on various Windows platforms for localization.

Download source, executable and sample

Introduction

Oh no! Is this another localization article?

Yes, it is.

But why? Don’t we have enough solutions already?

I have read several articles about localization and tried different solutions. Most of them are really good but none of them solved my problems. I needed something that would help me share resources between a WPF application and a Windows Store application. Also I wanted it to work in Windows Phone.

OK. So what’s the differences between these platforms?

WPF and Windows Phone (I think, I haven’t much phone development) both could use resx-files with the auto generated class file to access the resources. In Windows Store application resx-files are called resw-files, and no class file is generated. You work a bit different with strings on these platform.

I see. So how did you solved it?

I simply developed my own tool, ResToCode that converts resx/resw-file to a class file with all strings embedded directly in the class. It also contains properties to access the string easily. When you use the class it’s very similar to what resgen.exe normally generates.

OK. But I have heard that you could use a Portable Library to shared resources between these platforms. Why didn’t you use that?

It’s true, this works well but Portable Library isn’t available in the Express editions of Visual Studio that I’m using.

Aha! So the real problem is that you are greedy!

I also added some extra features. Like some methods to change language on the fly, verification that all keys exists on all platforms, etc.

But you are still greedy, aren’t you?

-

OK. Can you give me more details about your solution?

Sure! Here we go...

Features

ResToCode has the following features:

  • It generates a class that in code is very similar to the one that Visual Studio (resgen.exe) generates for resx-files.
  • Multi-language support. Several languages could be embedded in the generated class. The class provides methods to use the system language (this is done by default), or set a language manually.
  • Common string support. A few of your strings you probably want to have the same for all languages.
  • Missing string detection. If a string is missing in a language you will get a warning.
  • Format mismatch detection. If you for instance has this “{0} + {1} = {2}” in one language, and in other “{0} + {1} + {2} = {3}” you will get a warning.
  • Auto removal of mnemonics. In a WPF application you probably have strings like “_Save” that is used in a button or menu. This normally means that the user could press Alt+S to execute that command. Windows Store and Windows Phone apps doesn’t have support for mnemonics. So therefore the generated class automatically removes mnemonics on these platforms so you don’t need to duplicate your strings or do any kind of special coding.
  • Support for changing language on the fly.
  • Fallback support. If a string is missing in a language, the string from the default language will be used instead.
  • Works for desktop applications, Windows Store and Windows Phone applications. Probably in Silverlight and other platforms as well.
  • For each property a comment with the real string for each language. This will make Visual Studio showing you the real strings as a tool tip when you writing code.

Using ResToCode

ResToCode is a console application. You could very easily integrate this in Visual Studio with Pre-build event (see below). The following parameters is supported:

/namespace YourNamespace

YourNamespace is the namespace you want to use for the generated class.

/classname YourClassName

YourClassName is the name of the class ResToCode generate.

/commonfile commonstrings.resx

Use all strings from commonstrings.resx as common strings, i.e. they are used in all languages.

/fileX language-culture,filename.resx

X is the id of the file. First file should have id 1, the next id 2 and so on. Language-culture should be in the format en-US (American English), or just language like sv (Swedish). Note that file 1 will be the default language – this is used as language if the system language doesn’t match any of you languages. Strings will also be used from the default language if they are missing in the current language.

/output outputfile.cs

Write the output to outputfile.cs

/vsmode

Use the option when you run ResToCode from Visual Studio. This will make errors and warnings visible in Visual Studios Error list.

/notifymode

ResToCode make all the properties to access strings static by default, just like resgen.exe. One problem with this is that you can’t fully data bind to static properties, if you try to do this you will notice that you will get no notification when a property is changed. ResToCode will therefore use none-static properties if this flag is used. This will make it easy to change language on the fly.

/verifyonly

Just verify your strings, but don’t generate any output.

/noverify

Don’t verify anything.

/force

Force rebuild of the output. ResToCode will not regenerate the output file unless something was changed. Use this flag to always rebuild the output.

Example 1:

This example run ResToCode from a prompt. It will generate the file MyStringClass.cs, with the merged data from an English and Swedish resource file:

restocode /namespace MyNameSpace /classname MyStringClass /outputfile "C:\My code\MyStringClass.cs" /file1 en-US,"C:\My code\Resource-english-us.resx" /file2 sv,"C:\My code\Resources-swedish.resx"  

Example 2:

This example is more realistic and is an example how it could be executed from Visual Studio. $(ProjectDir) will be replaced with your project directory automatically by Visual Studio.

restocode /vsmode /namespace MyNameSpace /classname MyStringClass /outputfile  "$(ProjectDir)testcode.cs" /commonfile "$(ProjectDir)CommonStrings.resx" /file1  en-US,"$(ProjectDir)Resource-english.resx" /file2 sv,"$(ProjectDir)Resource-swedish.resx" 

Visual Studio integration

As said ResToCode is supposed to be used as a Pre-build event. You find this setting by:

  • Right click on your Project.
  • Select Properties.
  • Select Build Event
  • Enter the command line something like this:

    Image 1

When you build you project you will get warnings in Visual Studio (if the /vsmode flag is used):

Image 2

When you are Writing code you will get a tool tip containing the real strings for each language.

Image 3

Using the code

The syntax is slightly different if you are using “static mode” or “notify mode”.

Static mode

In C# it’s super easy to get access to the strings:

C#
string mystring = MyGeneratedClass.NameOfKey; 

In XAML you should create an instance of the class in your viewmodel:

C#
public class MyModel
{
    private TestClass _MyStrings = new TestClass();

    public TestClass MyStrings
    {
        get
        {
            return _MyStrings;
        }
    }
} 

Then you use it like this in XAML:

XML
<Label Content="{Binding MyStrings.ColorBlack}"/>

In desktop applications you could do a short cut. You don’t need to create an instance the string class, you could access static properties directly. Note that this doesn’t work in Windows Store applications:

XML
<Window x:Class="ResToCodeTest.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:rt="clr-namespace:ResToCodeTest"
 Title="MainWindow">

 <Grid>
  <Label Content="{x:Static rt:TestClass.ColorGreen}"/>
 </Grid>
</Window>

Notify mode

In C# you should access the strings like this:

C#
string mystring = MyGeneratedClass.Instance.NameOfKey;  

In XAML you should create an instance of the class in your viewmodel:

C#
public class MyModel
{
    private TestClass _MyStrings = new TestClass();

    public TestClass MyStrings
    {
        get
        {
            return _MyStrings;
        }
    }
} 

Then you use it like this in XAML:

XML
<Label Content="{Binding MyStrings.ColorBlack}"/>

Example projects

I have provided examples for WPF, Windows Store and Windows Phone application. It’s very simple but should be enough to understand how to use this. These are mode in the express editions of Visual Studio 2013. I think the desktop application will start in Visual Studio 2012, but I'm not sure about the other projects.

Windows Desktop

Image 4 Image 5

Windows Phone

Image 6

Windows Store

Image 7

Hint a tips

  • If you are using ResToCode, you don’t need to embed your resx-files in your assembly. Select properties of your resx-files and set Build Action to None.
  • If you are using “Notify mode”, you could access all strings from YouClassName.Instance.

Final notes

The code in ResToCode is kind of ugly. But it’s also quite straight forward so I haven’t spent much time to design it. Internally it uses System.Resources.ResXResourceReader to read resx-files. This works fine as long as it is only strings in your resx-file. If you add some other types of data you might get some strange problems – so don’t do that :-).

If you find any bugs just let me know. ResToCode was written in a few hours, but it working surprisingly well so I haven’t done any deep and careful testing. It does what I need it to do so I’m quite happy with it.

Changing language on the fly is a cool feature but it has two disadvantages as I see it. First it breaks the compatibility with resgen.exe a bit, since key properties aren’t static. Second it’s very hard to update all strings in the GUI. Labels, buttons are often quite easy since they are often databounded with the strings the directly. It’s harder with for instance list items were you generate the list in code. So use this feature wisely.

Credits

This article had a nice code snippet to parse the command line arguments which I used:

http://www.codeproject.com/Articles/3111/C-NET-Command-Line-Arguments-Parser

History

2014, 16 March
First edition.


License

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


Written By
PEK
Sweden Sweden
PEK is one of the millions of programmers that sometimes program so hard that he forgets how to sleep (this is especially true when he has more important things to do). He thinks that there are not enough donuts in the world. He likes when his programs works as they should do, but dislikes when his programs is more clever than he is.

Comments and Discussions

 
QuestionCan this be used with MS Prism modules Pin
Patrick Blackman15-Jun-14 13:41
professionalPatrick Blackman15-Jun-14 13:41 
Can this be used to localize ms prism modules so I don't have to manually add the resources to the main app project.
AnswerRe: Can this be used with MS Prism modules Pin
PEK15-Jun-14 19:43
PEK15-Jun-14 19:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.