Windows Presentation Foundation

Hello, WPF

WPF from Scratch
Navigation Applications
Content Model
Layout
Controls
Data Binding
Dependency Properties
Resources
Styles and Control Templates
Graphics
Application Deployment
Where Are We?

Layout

Introduction
Layout Basics
DockPanel
StackPanel
Grid
Canvas
Viewbox
Text Layout
Common Layout Properties
When Content Doesn't Fit
Custom Layout
Where Are We?

Controls

Introduction
What Are Controls?
Handling Input
Built-In Controls
Where Are We?

Data Binding

Introduction
Without Data Binding
Data Binding
Binding to List Data
Data Sources
Master-Detail Binding
Where Are We?

Styles and Control Templates

Introduction
Without Styles
Inline Styles
Named Styles
Element-Typed Styles
Data Templates and Styles
Triggers
Control Templates
Where Are We?

Resources

Introduction
Creating and Using Resources
Resources and Styles
Binary Resources
Global Applications
Where Are We?

Graphics

Introduction
Graphics Fundamentals
Shapes
Brushes and Pens
Transformations
Visual-Layer Programming
Video and 3-D
Where Are We?

Animation

Animation Fundamentals
Timelines
Storyboards
Key Frame Animations
Creating Animations Procedurally
Where Are We?

Custom Controls

Introduction
Custom Control Basics
Choosing a Base Class
Custom Functionality
Templates
Default Visuals
Where Are We?

ClickOnce Deployment

A Brief History of Windows Deployment
ClickOnce: Local Install
The Pieces of ClickOnce
Publish Properties
Deploying Updates
ClickOnce: Express Applications
Choosing Local Install versus Express
Signing ClickOnce Applications
Programming for ClickOnce
Security Considerations
Where Are We?

Global Applications

6.4. Global Applications

If you plan to distribute your applications worldwide, you may need to prepare different versions of the user interface for different regions. At a minimum, this involves translating text into the appropriate language. It may also involve other UI changes. You might need to adapt certain visuals to local cultural conventions. Or you might find that the original layout doesn't quite work after translation, because the words are all different lengths (although WPF's layout system makes it easy to build flexible layouts that will avoid that last problem).

It is possible to build different versions of your software for different markets. However, a more common approach is to build a single version that can adapt to different locales, usually by selecting suitable resource files at runtime. The ResourceManager infrastructure that WPF uses makes this fairly straightforward.

Microsoft makes a distinction between localization and globalization. Localization is the process of enabling an application to be used in a particular locale, by creating culture-specific resources such as translated text. Globalization is the process of ensuring that an application can be localized without needing to be recompiled. Using ResourceManager helps to globalize your application, because its runtime resource selection enables a single build of the application to be localized by supplying suitable resources. For more information on recommended globalization and localization practices in Windows, see Microsoft's internationalization site: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vboriInternationalization.asp (http://shrinkster.com/6m9).


When a ResourceManager is asked to retrieve a named resource stream, the first thing it does is determine which culture it should use. A culture is the combination of a language and location, and is typically represented as a short string. For example, en-US means the English language, as spoken in the U.S. The en-GB culture represents English as spoken in Great Britain. The first two letters indicate the language and the last two the region. The reason both language and location are specified is that there are often variations in dialect and idiom even when two cultures ostensibly share a language. For example, one of the authors of this book hails from en-GB, and therefore prefers "color" to be spelled "colour."

The ResourceManager.GetStream method takes a CultureInfo object as a parameter. If you wish to use the end user's configured culture, you can retrieve a CultureInfo from the CurrentUICulture property of Thread.CurrentThread.

Although executables usually have resources compiled in, the ResourceManager will look for culture-specific resources before resorting to the built-in ones. It will look in the directory containing the application for a subdirectory named for the culture. So, if you are running in a French Canadian culture, it will look for an fr-CA subdirectory containing a file called MyApp.resources.dll, where MyApp is the name of your application or component. If that doesn't exist, it will then look for the same file in a directory called fr. This means that if your translation budget doesn't stretch to producing different versions for all of the various French-speaking regions of the world, you can instead provide a single set of French resources that will be used in any French-speaking region. Only if neither of these subdirectories exists will it resort to using the built-in resources.

The resource DLLs that the ResourceManager looks for are called satellite resource assemblies , so called because they are small assemblies associated with a larger assembly nearby.

Note that if you supply a satellite assembly, you are not required to provide localized versions of all of the resources. It might be that some of the resources you embed in your main assembly work just fine for all cultures. For example, the application shown in Figure 6-6 had an embedded bitmap called Sunset.jpg. The sun sets in most parts of the world, so while you might need to do something special for Arctic and Antarctic editions, the basic Sunset.jpg probably works for most cultures. It would be a bit of a waste of space for every satellite resource assembly to contain a copy of the same image. Fortunately, they don't have toif a particular named resource is not present in a satellite resource assembly, the ResourceManager will fall back on the built-in resources.

You can think of satellite resource assemblies as containing just the differences between the built-in resources and those required for the target culture. Any common resources will live in the main assembly alone. An assembly in a language-specific but location-generic subdirectory (e.g., in the fr subdirectory) contains resources that need to be different for the specified language. And then the fully culture-specific subdirectories (e.g., fr-CA, fr-FR, fr-BE, etc.) contain only those resources that need to be adjusted to take into account local idioms. (In this context a "resource" is a single stream as retrieved by the ResourceManager, rather than an object retrieved from a ResourceDictionary.)

6.4.1. Building Localizable Applications with XAML

Because XAML is compiled into BAML resources that are retrieved using a ResourceManager, localizability is an intrinsic feature of any WPF application built using XAML. However, there is currently no built-in support for localizing WPF applications in Visual Studio 2005, so there are a few manual steps involved.

If you build a UI in XAML, localization effectively occurs one XAML file at a timethe ResourceManager cannot go more fine-grained than a single BAML resource, so each BAML resource is either localized or not. Since there is a close relationship between a XAML file and its code-behind file, however, it is important that the localized BAML resource has the same essential structure as the original. In principle, you could achieve this by writing a new XAML file for the localized version and trying to keep its structure the same. However, there is a more robust way of guaranteeing consistency.

Instead of authoring a set of XAML files for every culture, you can write one master set of XAML filesone for each window or page in your application. Then, for each culture you wish to support, you can use a tool to generate culture-specific satellite resource assemblies containing localized resources. You supply the tool with configuration files indicating how the resources should be modified in order to create the localized versions. Figure 6-7 illustrates the overall process.

This is a slightly long-winded process. By the time the final release of WPF ships, this will no doubt be better streamlined and integrated into Visual Studio 2005. For now, welcome to the wonderful world of pre-release software.


Figure 6-7. Localization process


First, you must make sure the project is set up to build a localizable application by specifying a default UI culture. At the time of writing, there was no way of doing this from within Visual Studio 2005, so you must edit the .csproj file using a text editor. Add a UICulture element inside the PropertyGroup element (it doesn't matter where the UICulture element appears within this section). Set it to the default culture for your applicationthe culture in which you will create the main resources. This will cause Visual Studio 2005 to put all of the binary resources into a satellite resource assembly for this default culture. Example 6-28 shows some sample markup that achieves this result.

Example 6-28. Specifying a UI culture for your project
<Project DefaultTargets="Build"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    ...
    <UICulture>en-US</UICulture>
    ...
  </PropertyGroup>

  ...

Next, you must add Uids to your XAML. A Uid is a special attribute on a XAML element indicating content that may require localization. The localization configuration file containing localization instructions will use Uids to indicate which elements are being changed. Example 6-29 shows a TextBlock with a Uid.

Example 6-29. A Uid
<TextBlock x:Uid="TextBlock_1">Hello, world</TextBlock>

You can add these by hand if you want. Or you can generate them automatically using msbuild. (msbuild is the command-line tool for building projects. Visual Studio 2005 uses the same build technology, but msbuild offers more control. For example, it lets you get at this Uid generation feature of the WPF build system.) To add Uids to your XAML automatically, run this command:

    msbuild /t:updateuid MyProject.csproj

If you have done this already, and have subsequently edited your XAML, you may want to check that you've not ended up with any duplicated Uids. You can do this with the following command:

    msbuild /t:checkuid MyProject.csproj

Now you can build the project, either by using VS 2005 or by running msbuild from the command line, passing just the project filename as a parameter. You should now find that as well as building an EXE or DLL, your project also adds a satellite resource assembly in a subdirectory. (The subdirectory will be the one you named when you added the UICulture element to the project file.)

The next step is to create the configuration file that will direct the localization process. This file will contain all localized items, such as translated strings. You can create the skeleton of this file using the LocBaml command-line tool. This tool examines resource assemblies for BAML streams and builds a file containing one line for each localizable piece of information in the file. You can then put your translated strings and whatever else is required into this file.

In the current preview builds of WPF, LocBaml is supplied in source code form only, so you will need to build it before you can run it. You can find the code in the WinFX SDK documentation. In the Avalon Globalization and Localization How-to Topics section, find the "Localize an Application" topic. This provides the code for LocBaml.


Example 6-30 shows how to run LocBaml to generate the skeleton configuration file.

Example 6-30. Generating a CSV file with LocBaml
LocBaml bin\Debug\en-US\MyApp.resources.dll /out:MyAppResources.csv

This will create a CSV file. Table 6-1 describes each of the columns in the order in which they appear in the CSV file. To localize the resource, edit the Value column. (Note that the CSV file doesn't contain a heading lineit depends entirely on the column positions.)

Table 6-1. Columns generated by LocBaml

Column

Description

Baml Name

Identifies the BAML stream; the value will be of the form AssemblyManifestStreamName:SubStream Name.

Resource Key

Identifies the localizable resource; the value will be of the form Uid:Element Type.$Property.

Localization Category

An entry from the LocalizationCategory enumeration, indicating what kind of content this is.

Readable

Indicates whether the resource is visible for translation.

Modifiable

Indicates whether this value can be modified during translation.

Comments

Localization comments.

Value

The value of this resource.


Example 6-31 shows a line from one of these configuration files. (It has been split across several lines here to make it fit. In a real file, this would be on a single line.)

Example 6-31. Example configuration file
HelloApp.g.fr-FR.resources:window1.baml,
TextBlock_1:System.Windows.Controls.TextBlock.$Content,
None,True,True,,Bonjour monde

Once you have translated all of the Values, you can then run LocBaml again to generate the new resource DLL. You must pass in the path of the original resource DLL, the path of the CSV file containing translations, a target directory, and the target culture, as shown in Example 6-32. (Note that this example has been split across multiple lines to fit into the book. It should be entered as a single line in practice.)

Example 6-32. Generating a resource DLL with LocBaml
LocBaml /generate bin\Debug\en-US\MyApp.resources.dll /trans:MyAppResource.csv
  /out:bin\Debug\en-GB /cul:en-GB

This will generate a new satellite resource assembly in the specified directory, targeting the chosen culture. (If you want to build several resource assemblies, create one CSV file for each culture and run LocBaml once for each file.) If you place the resulting resource assembly in a subdirectory of the application's directory named after the culture, it will automatically be picked up at runtime if the application is run with that particular culture selected.


©2008 FAQ - WPF Labs - Discuss - Terms of Use - Privacy Policy - About WPF
- Interview Questions - Sharepoint Articles - Interview Questions Resource Library - All about LINQ - MS Knowledgebase Articles - Electronics and Hardware discussions