Saturday, March 27, 2010

WinForm : Making Localization-aware UI

When an application is expected to support localization, more additional effort is generally needed to make UI forms more flexible for long localized strings. For example, if the resource strings are localized in German, its localized text will be typically longer than English. How can we achieve this flexibility in .NET WinForms?

Let’s look at a tiny sample.

I marked two red boxes (one for label, the other for button) where the potential string truncation can occur in localized build.

Note: localization process can vary for each software company but two typical localizations are ‘Pseudo Localization’ and real ‘Localization.’ Pseudo Loc is normally done by adding some random text (such as #!@#&) before and/or after the resource string. By doing this automatically in the build process, the developer/tester can detect resource truncation problem earlier. The earlier find the problem, the easier to fix. Real Localization is typically performed after UI freeze (or RTM) since it’s expensive and takes long time.

So what would happen if it’s localized? Let’s assume the label (Here is the…) was pseudo localized and the button (Save Report) is localized in French (In reality, this kind of mix can occur if resource localization is half way done)

For the label text, random string #@!# was added before and after the resource string. So actually label text should be “#@!# Here is the summary. Please review the summary. #@!#”

For button text, Save Report was translated to “Enregistrer le rapport” in French. As you can see both resource strings are truncated. Let’s look into it.

Here Button is a little easier. The button is located in a Table Layout control and in the table layout cell, there seems enough room for long localized resource string.

In this case, setting AutoSize property of the button to TRUE and setting Anchor to Top,Right should do the trick.

With this setting in Properties windows, the following code (in C#) will be added to *.designer.cs file.
this.btnSaveReport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnSaveReport.AutoSize = true;

Now the other control is Label. Label control sets, by default, AutoSize to true when one drags and drops the control to the WinForm from ToolBox. If one changed the property, it should be reset back to TRUE. But setting AutoSzie to TRUE isn’t enough here. This is because even if the Label control tries to autosize text but some other control is blocking the autosizing. The culprit is TableLayout control. Looking at the Rows property of the TableLayout control in Properties window:

Here Row2, which is the container of Label control, has Absolute size 20 pixels. Label control can expand in multiple rows if AutoSize property is TRUE, but since the Row height is limited to 20 pixels, the Label control cannot draw a second line and just truncates the string in one line. This kind of problem can be solved by settting Row2 size type to AutoSize. If it’s set, then Label control will display long resource string in two lines as follows. (well, button control is also shown correctly here)

One thing that is worthy noting here is that if one sets AutoSize type in a TableLayour Row (or Column), sometimes the control in the cell does not have decent space and look collapsed. If one sets Absolute 40 pixels in a Row, row’s height is always 40 pixels, but once sets AutoSize type Row height can be reduced to 13 pixels automatically. The UI shall look ugly then. To solve this problem, we can use Margin property in the Label control (or any other contained control). If Margin Top/Margin Bottom property value is increased, the margin space will be kept accordingly which displays the control nicely.