The following graphics show the output of the Run dialog box sample.
English:
.png)
German:
.png)
Designing a Global Run Dialog Box
This example produces a Run dialog box by using WPF and XAML. This dialog box is equivalent to the Run dialog box that is available from the Microsoft Windows Start menu.
For the complete sample, see Globalization Run Dialog Sample.
Some highlights for making global dialog boxes are:
Automatic Layout
In Window1.xaml:
<Window SizeToContent="WidthAndHeight">
The previous Window property automatically resizes the window according to the size of the content. This property prevents the window from cutting off content that increases in size after localization; it also removes unneeded space when content decreases in size after localization.
<Grid x:Uid="Grid_1">
Uid properties are needed in order for WPF localization APIs to work correctly.
They are used by WPF localization APIs to track changes between the development and localization of the user interface (UI). Uid properties enable you to merge a newer version of the UI with an older localization of the UI. You add a Uid property by running msbuild /t:updateuid RunDialog.csproj in the Windows SDK command shell. This is the recommended method of adding Uid properties because manually adding them is typically time-consuming and less accurate. You can check that Uid properties are correctly set by running msbuild /t:checkuid RunDialog.csproj.
The UI is structured by using the Grid control, which is a useful control for taking advantage of the automatic layout in WPF. Note that the dialog box is split into three rows and five columns. Not one of the row and column definitions has a fixed size; hence, the UI elements that are positioned in each cell can adapt to increases and decreases in size during localization.
|
<Grid.ColumnDefinitions>
<ColumnDefinition x:Uid="ColumnDefinition_1" />
<ColumnDefinition x:Uid="ColumnDefinition_2" />
|
The first two columns where the Open: label and ComboBox are placed use 10 percent of the UI’s total width.
|
<ColumnDefinition x:Uid="ColumnDefinition_3" SharedSizeGroup="Buttons" />
<ColumnDefinition x:Uid="ColumnDefinition_4" SharedSizeGroup="Buttons" />
<ColumnDefinition x:Uid="ColumnDefinition_5" SharedSizeGroup="Buttons" />
</Grid.ColumnDefinitions>
|
Note that of the example uses the shared-sizing feature of Grid. The last three columns take advantage of this by placing themselves in the same SharedSizeGroup. As one would expect from the name of the property, this allows the columns to share the same size. So when the “Browse…” gets localized to the longer string “Durchsuchen…”, all buttons grow in width instead of having a small “OK” button and a disproportionately large “Durchsuchen…” button.
Xml:lang
Xml:lang="en-US"
Notice the xml:lang Handling in XAML placed at the root element of the UI. This property describes the culture of a given element and its children. This value is used by several features in WPF and should be changed appropriately during localization. This value changes what language dictionary is use to hyphenate and spell check words. It also affects the display of digits and how the font fallback system selects which font to use. Finally, the property affects the way numbers are displayed and the way texts written in complex scripts are shaped. The default value is “en-US”.
Building a Satellite Resource Assembly
In .csproj:
<UICulture>en-US</UICulture>
Notice the addition of a UICulture property. When this is set to a valid CultureInfo value such as en-US, building the project will generate a satellite assembly with all localizable resources in it.
<Resource Include="RunIcon.JPG">
<Localizable>False</Localizable>
</Resource>
The RunIcon.JPG does not need to be localized because it should appear the same for all cultures. Localizable is set to False so that it remains in the language neutral main assembly instead of the satellite assembly. The default value of all noncompilable resources is Localizable set to True.
Localizing the Run Dialog
Parse
After building the application, the first step in localizing it is parsing the localizable resources out of the satellite assembly. For the purposes of this topic, use the sample LocBaml tool which can be found at LocBaml Tool Sample. Note that LocBaml is only a sample tool meant to help you get started in building a localization tool that fits into your localization process. Using LocBaml, run the following to parse: LocBaml /parse RunDialog.resources.dll /out: to generate a “RunDialog.resources.dll.CSV” file.
Localize
Use your favorite CSV editor that supports Unicode to edit this file. Filter out all entries with a localization category of “None”. You should see the following entries:
Resource Key
|
Localization Category
|
Value
|
Button_1:System.Windows.Controls.Button.$Content
|
Button
|
OK
|
Button_2:System.Windows.Controls.Button.$Content
|
Button
|
Cancel
|
Button_3:System.Windows.Controls.Button.$Content
|
Button
|
Browse...
|
ComboBox_1:System.Windows.Controls.ComboBox.$Content
|
ComboBox
| |
TextBlock_1:System.Windows.Controls.TextBlock.$Content
|
Text
|
Type the name of a program, folder, document, or Internet resource, and Windows will open it for you.
|
TextBlock_2:System.Windows.Controls.TextBlock.$Content
|
Text
|
Open:
|
Window_1:System.Windows.Window.Title
|
Title
|
Run
|
Localizing the application to German would require the following translations:
Resource Key
|
Localization Category
|
Value
|
Button_1:System.Windows.Controls.Button.$Content
|
Button
|
OK
|
Button_2:System.Windows.Controls.Button.$Content
|
Button
|
Abbrechen
|
Button_3:System.Windows.Controls.Button.$Content
|
Button
|
Durchsuchen…
|
ComboBox_1:System.Windows.Controls.ComboBox.$Content
|
ComboBox
| |
TextBlock_1:System.Windows.Controls.TextBlock.$Content
|
Text
|
Geben Sie den Namen eines Programms, Ordners, Dokuments oder einer Internetresource an.
|
TextBlock_2:System.Windows.Controls.TextBlock.$Content
|
Text
|
Öffnen:
|
Window_1:System.Windows.Window.Title
|
Title
|
Run
|
Generate
The last step of localization involves creating the newly localized satellite assembly. This can be accomplished with the following LocBaml command:
LocBaml.exe /generate RunDialog.resources.dll /trans:RunDialog.resources.dll.CSV /out: . /cul:de-DE
On German Windows, if this resources.dll is placed in a de-DE folder next to the main assembly, this resource will automatically load instead of the one in the en-US folder. If you do not have a German version of Windows to test this, set the culture to whatever culture of Windows you are using (i.e. en-US), and replace the original resources.dll.
Satellite Resource Loading
MyDialog.exe
|
en-US\MyDialog.resources.dll
|
de-DE\MyDialog.resources.dll
|
|---|
Code
|
Original English BAML
|
Localized BAML
|
Culturally neutral resources
|
Other resources in English
|
Other resources localized to German
|
The .NET framework automatically chooses which satellite resources assembly to load based on the application’s Thread.CurrentThread.CurrentUICulture. This defaults to the culture of your Windows OS. So if you are using German Windows, the de-DE\MyDialog.resources.dll loads, if you are using English Windows, the en-US\MyDialog.resources.dll loads. You can set the ultimate fallback resource for your application by specifying the NeutralResourcesLanguage in your project’s AssemblyInfo.*. For example if you specify:
[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
then the en-US\MyDialog.resources.dll will be used with German Windows if a de-DE\MyDialog.resources.dll or de\MyDialog.resources.dll are both unavailable.