четвер, 3 квітня 2014 р.

WPF Application Localization

How to translate a WPF Application into multiple languages?

There are two common approaches for that.

1. Localization using ResX file.

Localization using .ResX files is the oldest approach and was the main mean to translate WinForms applications. 

When localising using ResX, you need to have all of your localizable resources in the separate resource file (defined as XML). If you need to use these strings from .XAML files, you access them with some helper class. 

The code in will look like this:

<TextBlock Text="{Resx ResxName=MyApp.TestWindow, Key=MyText}"/>

Then you create translated version of the resource files for different cultures, and .NET Framework will load them automatically for you. 

This method is still widely used, especially when you need localize resources in binary format, like images and audio files.

However when you have a lot of UI controls, supporting strings in the separate files can be very painful, as you need to constantly keep strings in resources in sync, removing unused strings and adding new ones.

Also misspelling a resource key or having such key to be absent in resources will cause a run-time error, which is also hard to detect.

If you interested more in localising using .ResX files, you can read the following article on CodeProject.

2. Native XAML Localization Approach

While designing WPF, engineers at Microsoft implemented a new approach to translate XAML files.

The idea is to let the developers design their XAML in the native languages and then extract all the strings in a separate file and translate them.

When using this approach, your controls in XAML files will look as usual:

<TextBlock Text="This is a localisable text"
Then when there is time for localization, you run a special tool to update UIDs for all the elements:

msbuild /t:updateuid project.csproj

This will update your XAML files controls to be like this:

<TextBlock Text="This is a localisable text" x:Uid="TextBlock_1"/>

Notice the x:Uid attribute which is added to the element. This is a resource key, which will be used to identify an UI element on the form.

You may change the x:Uid value to anything you want, but it is required to be unique in the XAML file. 

This approach allows you translate your application effortlessly even on the late stage, when all the development is done.

External Tools

There are few tools available to extract strings and to generate satellite resource assemblies with translation.

Microsoft has released a sample tool with source codes called LocBaml, which is already pretty useful and can be even more extended further to suite additional needs. With LocBaml you can extract strings from your project into the .csv format, then translate them and generate localized resources.

The main disadvantage of it is that you need to use command line a lot, and the output .csv format have a not very user-friendly format, but just a dump of localisable resources of your project.

Visual LocBaml

I've written a Visual LocBaml - a tool for Xaml translation and localization. It is made in such a way to seamlessly integrate into the development process and to make a localization as simple as possible.

Visual LocBaml will not only extract strings and generate satellite assemblies for you. It serves as a translation database, keeping all you strings with corresponding translation. This allows you to quickly find new and changed strings which needs to be translated.

Also it is very easy to translate strings or to export/import strings for professional translation company:

You can try it yourself right now, it is very easy to use!

неділя, 26 вересня 2010 р.

Border with exact 1 pixel width or height regardless of the screen DPI

Sometimes it is required to make border size exact of 1 screen pixel width or height in WPF.

In usual 96 DPI environment is is pretty simple, just specify "SpansToDevicePixels" property to "True":
<Border Height="1" SnapsToDevicePixels="True" Background="Gray" />

However, if the DPI is different, you may receive unexpected results.
If the DPI < 96, the line may not be visible at all, and if DPI > 96, two lines may appear sometimes instead of one.

To fix this, you need to specify height of the border in device independent pixel to exact match screen pixel. E.g for the DPI = 125, the Height should be 0.8.

To achieve this I create a special class PixelBorder and override MeasureOverride method:
public class PixelBorder: Border
    protected override Size MeasureOverride(Size constraint)
        PresentationSource presentationSource = PresentationSource.FromVisual(this);
        return new Size(

And use it where needed:
<local:PixelSeparator SnapsToDevicePixels="True" Background="#AAAAAA" Margin="4"/>

This border will be stretched horizontally or vertically depending on parent panel.

середа, 23 грудня 2009 р.

Great article on AppDomain:

четвер, 15 жовтня 2009 р.

UV Outliner 1.3 is out

Finally, my tiny WPF project is released. It is UV Outliner.

I am a big fan of outliners.

It is astonishing what amount of information in our everyday life has a hierarchical nature.
I always wanted to be able to play with such information. Plans for life or for the day, travel information, meeting schedules, business plans, novels, or even blog posts are all examples of hierarchical information.

So I decided to share the results of my work with other people like me.

I hope UV Outliner will become a part of your life and will help you to be more productive.


субота, 13 червня 2009 р.

Correct way to keep selection in TextBox and RichTextBox visible after focus lost in WPF

WPF controls: TextBox and RichTextBox have no HideSelection property. Due to this, it is a bit tricky to make them to show selection after focus lost.

There are two possible solutions.

1. Defining separate focus scope in XAML
2. Adding and event handler (LostFocus) and set Handled property of RoutedEventArgs to true in code.

As the second one seems to be tricky, I will show how to implement this behavior with the first concept:


<TextBox Margin="5">Some text here</TextBox>

<StackPanel Grid.Row="1" FocusManager.IsFocusScope="True">
  <ComboBox Margin="5">
  <ComboBoxItem IsSelected="True">123</ComboBoxItem>


This code will create window with two controls (TextBox and ComboBox):

As you can see, both controls can have focus simultaneously. This happens because of the FocusManager.IsFocusScope property set to true which makes second control to be in a separate focus scope.

However, if new window is opened, focus on both controls will be lost.

You can read more about focus management in WPF here:

середа, 11 лютого 2009 р.

How to insert image into FlowDocument at runtime

To insert image into FlowDocument at runtime you can use the following code:

FlowDocument document = new FlowDocument();
Image image = new Image();
BitmapImage bimg = new BitmapImage();
bimg.UriSource = new Uri("c:\temp\image.png", UriKind.Absolute);
image.Source = bimg;
document.Blocks.Add(new BlockUIContainer(image));

пʼятниця, 7 листопада 2008 р.

How to set initial focus to specific WPF control in XAML

Setting initial focused control in WPF is easy. Just use the FocusManager.FocusedElement attached property:

<Window FocusManager.FocusedElement="{Binding ElementName=MyEdit}" >
<TextBox Name="MyEdit" />