DCSIMG
WPF Localization - On-the-fly Language Selection - Essential XAML

WPF Localization - On-the-fly Language Selection

Download code ver 1.3 from here.

 

Many of my customers asked me:

How WPF supports localization and globalization?

Is there any built-in mechanism for choosing a language on-the-fly, at runtime and without closing any window?

How do I translate formatted text with parameters?

Well..., you know the story,... aren't you!? No? So start by reading this, and this. Still confused? continue with this and also this.

 

As you can see, there is more than one solution. Each has its pros and cons. The WPF official language support provides a complex localization set of API's, and a bizarre SDK tool for translation and creation of localized assemblies. Others provide unofficial great ideas for localizing WPF based on .NET 2.0 resource files, WPF resource dictionary and XML.

 

I decided to share another mechanism for localizing WPF applications.

Download the code from here.

 

Why did I bother to invent another solution, and why would you want to use my solution

  1. It provides an option for replacing languages at runtime, on-the-fly
  2. It performs better than a lame XML, XPath based binding solution
  3. It can be used via Styles, Control Templates and Data Templates
  4. It translates a formatted text with parameters, using default and custom formatters
  5. It provides a Translate custom markup-extension to write an elegant XAML

 

I will start by discussing the markup snippet bellow:

<Window x:Class="Tomers.WPF.Localization.MainWindow" x:Name="Root"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:loc="http://schemas.tomer.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Tomers.WPF.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2006"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"

Background="{StaticResource WindowBrush}"

loc:Translate.Uid="0"

Title="{loc:Translate}"
Width="{loc:Translate}"
Height="{loc:Translate}"
FlowDirection="{loc:Translate}">

<Window.Resources>
<DataTemplate DataType="{x:Type local:Data}">
<TextBlock Margin="8" HorizontalAlignment="Left">
<TextBlock.Text>
<loc:Translate>
<Binding Path
="Uid" />
<Binding Path
="ID" />
</loc:Translate
>
</TextBlock.Text>
<TextBlock.Foreground>
<loc:Translate>
<Binding Path
="Uid" />
</loc:Translate
>
</TextBlock.Foreground>
</TextBlock>
</DataTemplate>
</Window.Resources>

<StackPanel x:Name="_panel">

<Label loc:Translate.Uid="1"
Content="{loc:Translate}"
FontSize="14" />

<TextBlock loc:Translate.Uid="2" FontSize="16">
<TextBlock.Text>
<loc:Translate>
<Binding ElementName="Root" Path
="Width" />
<Binding ElementName="Root" Path
="Height" />
</loc:Translate
>
</TextBlock.Text>
</TextBlock>

<TextBlock loc:Translate.Uid="3"
Text="{loc:Translate}"
Background="{loc:Translate}"
Width="{loc:Translate}"
Height="{loc:Translate}" FontSize="18" />

<TextBlock FontSize="18">
<TextBlock.Text>
<loc:Translate>
<Binding ElementName="Root" Path
="Uid" />
</loc:Translate
>
</TextBlock.Text>
</TextBlock>

<ContentControl x:Name="_elementI" FontSize="20" />
<ContentControl x:Name="_elementII" FontSize="20" />

<Button loc:Translate.Uid="7"
Margin="8"
HorizontalAlignment="Right"
Content="{loc:Translate}"
Width="200"
Click="Button_Click" FontSize="16" />

</StackPanel>
</
Window>

image image   imageimage

As you can see, the markup snippet produces the window above. When clicking the "Click to change language" button, all the elements attached with the "loc:Translate" custom markup-extension, are automatically have new values: In our case the language, alignment, size, position, color and other.

 

So why did I choose to use a custom markup extension, what's wrong with a simple Data Binding markup

Well, this is the magic of my solution. It is possible to use a complex binding expression indeed, for example:

<Label Content="{Binding Source={x:Static loc:LanguageContext.Instance}, Path=Dictionary, Mode=OneWay
Converter={StaticResource languageConverter}, ConverterParameter=2}
" />

But as you can see, it's very long expression. Now try to imagine how long it will be if you pass parameters...

 

What's in the package

There are few types you should know before you start localizing:

  1. LanguageDictionary - This is an abstract class. It provides an abstraction for translating values by exposing two important methods: Load and Translate. The Load method loads the repository with data for each locale, and the Translate method translates a key-value pair into locale value from the repository. For example, I wrote a XmlLanguageDictionary class that loads and stores an XML language file inside a dictionary (you can find it in the LocalizationDemo project).
  2. LanguageContext - This singleton type holds the culture and the dictionary of the active language. It also plays an important role by notifying on culture change.
  3. LanguageConverter - This important type calls the active dictionary to translate values each time a language is replaced. The language converter is instantiated by the TranslateExtesnion during the internal-binding operation (see TranslateExtesnion type bellow). The LanguageConverter implements both IValueConverter and IMultiValueConverter interfaces.
  4. TranslateExtension - This is the magic of this solution. It provides the user an option to bind a localized-property to the language dictionary using a simple and short markup within XAML, as demonstrated in the markup snippet above. By extracting the target element and the dependency property, it binds the LanguageContext.Dictionary to the targets property.

 

How to use it

First, you have to create your own language-dictionary by deriving LanguageDictionary. You can also start by using my XmlLanguageDictionary, provided as a lame example inside the LocalizationDemo project.

Second, you should create and register a dictionary instance for each language and select the default one, before you create any localized UI element. See the markup bellow:

    /// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
LanguageDictionary.RegisterDictionary(
CultureInfo.GetCultureInfo("en-US"),
new XmlLanguageDictionary("Languages/en-US.xml"));

LanguageDictionary.RegisterDictionary(
CultureInfo.GetCultureInfo("he-IL"),
new XmlLanguageDictionary("Languages/he-IL.xml"));

LanguageContext.Instance.Culture = CultureInfo.GetCultureInfo("en-US");

base.OnStartup(e);
}
}

Now, use the Translate markup extension to localize elements as demonstrated above.

 

To translate a simple element with no parameters use the following syntax (The uid value, Content and FontSize should be keys in your dictionary back-storage - see my xml files for an example):

<Label loc:Translate.Uid="1" Content="{loc:Translate}" FontSize="{loc:Translate}" />

 

To translate an element with parameters use the following syntax

<TextBlock loc:Translate.Uid="2" FontSize="16">
<TextBlock.Text>
<loc:Translate>
<Binding ElementName="Root" Path
="Width" />
<Binding ElementName="Root" Path
="Height" />
</loc:Translate
>
</TextBlock.Text>
</TextBlock>

 

To translate an element with a dynamic Uid, use the previous syntax, where the Uid must be the first parameter (this is a great solution for styles and templates):

<TextBlock FontSize="18">
<TextBlock.Text>
<loc:Translate>
<Binding ElementName="Root" Path="Uid" />
</loc:Translate>
</TextBlock.Text>
</TextBlock>

 

There are several more issues that should be considered, also the code should be refactored for production. Use it on your own risk.

Download code ver 1.0 from here.

Download code ver 1.1 from here.

 

Update: On 13-Aug-2008

- Markup extension bug fixed

- Fully supported on both Blend and Cider designers

- Default fallback value was added

- Demo visuals improvements


Download code ver 1.2 from here.

 

Update: On 06-Feb-2009

- Uid's can be provided directly via Translate markup (now works with Setters - see demo)

- Demo upgrade to support new feature


Download code ver 1.3 from here.

 

Published Tuesday, October 30, 2007 11:55 PM by Tomer Shamam

Comments

# re: WPF Localization - On-the-fly Language Selection

Friday, November 09, 2007 5:44 PM by C. Marius

Hi,

How about support for Blend 2(September CTP). As I lost design support in Blend, it gets pretty impossible to use. I rather use the simple solution of Content={x:Static p:Resources.MyResourceName} which offers design-time support for VS2008 and Blend. Isn't something that could be done for this?

Thank you (c_marius@msn.com)

# re: WPF Localization - On-the-fly Language Selection

Sunday, November 11, 2007 2:15 PM by Tomer Shamam

Hi Marius,

Indead, there is a problem with Blend and Custom Markup Extensions. Blend 2 can deal with it, but not 100% (you will not get the translated values at design time, but at least it will show you the UI).

You can always use a Binding expression with a custom Value Converter instead of my Translate extension, but you should write alot of markup for each element (Path, Source, Converter, Parameter, etc).

Currently, I'm working on another solution for design time, using Data Provider.

# re: WPF Localization - On-the-fly Language Selection

Thursday, December 06, 2007 9:53 AM by Irfan Baig

Hi

What about using resources in code? Can you provide any samples?

# re: WPF Localization - On-the-fly Language Selection

Thursday, December 06, 2007 6:08 PM by Tomer Shamam

Hi,

You should bind your properties to the dictionary from code:

Binding binding = new Binding("Dictionary");

binding.Source = LanguageContext.Instance;

LanguageConverter converter = new LanguageConverter(uid, vid);

binding.Converter = converter;

BindingOperations.SetBinding(yourTargetObject, yourTargetProperty, binding);

You can wrap this code in a class, lets say: LanguageBinder, to prevent writing this code over and over again.

Tomer

# re: WPF Localization - On-the-fly Language Selection

Monday, March 31, 2008 7:12 AM by Evgeni

Tomer Shalom!

Nice work you did here, I really like this approach. I have one question regarding implementation: when I passed over your code, I saw you using two way binding (when you creating binding inside markup extension). Well, I expected to use one way binding, because I interesting to monitor only source changes. However, when I changed to one way, it stopped to work. In addition, I saw that no one anymore subscribing to "PropertyChanged" event of the dictionary. Could you please explain this point? (why one way binding is not works here).

Thanks,

Evgeni

# re: WPF Localization - On-the-fly Language Selection

Wednesday, July 23, 2008 11:30 AM by Xavi

There is a bug in your code:

If you are using a DataTemplate in a UserControl, in TranslateExtension.ProvideValue method, you receive a System.Windows.SharedDp object in service.TargetProperty. As you make a cast to DependencyObject type, it returns "this", so translation is not made.

# re: WPF Localization - On-the-fly Language Selection

Wednesday, July 23, 2008 11:43 AM by Tomer Shamam

Hi Xavi,

As I already wrote: "the code should be refactored for production. Use it on your own risk"

This means that you may find one or more BUGS in my code.

I only gave the concept.

Cheers

# re: WPF Localization - On-the-fly Language Selection

Wednesday, July 23, 2008 11:53 AM by Xavi

Maybe you have missunderstood me. My purpose was improving your great idea and learning how to fix the bug I found.

I didn't know you were only interested in giving th concept, not tracking its feedback.

Thanks anyway.

# re: WPF Localization - On-the-fly Language Selection

Wednesday, July 23, 2008 12:14 PM by Tomer Shamam

Thanks for finding a BUG. It will help others to know about it and fix it.

# re: WPF Localization - On-the-fly Language Selection

Thursday, July 24, 2008 12:36 PM by Benny

Tomer,

What if you want to localize an error message that is generated in code?

# re: WPF Localization - On-the-fly Language Selection

Thursday, July 24, 2008 3:20 PM by Tomer Shamam

LanguageDictionary dictionary = LanguageDictionary.GetDictionary(

  LanguageContext.Instance.Culture);

string message = dictionary.Translate(

  "NotEnoughMemory", "Message", typeof(string)) as string;

 

English Entry:

<Value Id="NotEnoughMemory" Message="There is not enough memory" />

Hebrew Entry:

<Value Id="NotEnoughMemory" Message="אין מספיק זכרון" />

Cheers

# re: WPF Localization - On-the-fly Language Selection

Thursday, July 24, 2008 3:40 PM by Tomer Shamam

I have also updated the code to version 1.1. Now you can use a simple form to get any message from code:

string message = LanguageDictionary.Current.Translate<string>("AnyKey", "AnyMessage");

Hope this helps.

# re: WPF Localization - On-the-fly Language Selection

Saturday, July 26, 2008 6:52 PM by SeriousM

hey, please have a look at my engine! i dont have these problems andmore and it works faster tham yours :)

www.codeplex.com/WPFLocalizeExtension

# re: WPF Localization - On-the-fly Language Selection

Wednesday, July 30, 2008 6:40 AM by inTagger

Try my cool tool and pattern for WPF application localization intagger.blogspot.com/.../wpf-application-localization-pattern_29.html

# re: WPF Localization - On-the-fly Language Selection

Wednesday, July 30, 2008 10:21 AM by inTagger

Hail Tomer Shamam! The great miss of your solution (may be of Blend && VS) is impossibility of editing UI in Blend and VS designers (exception is thrown).

Look at my solution intagger.blogspot.com/.../wpf-application-localization-pattern_29.html i think it's simpler and allow seeing all localized values in Blend or VS designers.

# re: WPF Localization - On-the-fly Language Selection

Wednesday, July 30, 2008 11:41 AM by Tomer Shamam

Hi inTagger,

Nice solution, but the great miss of your solution may be passing arguments for translation. For example: "You have {0} new message!", where {0} can be retrieved via binding.

Also you didn't provide an option to replace the dictionary source. It should be always XAML based ResourceDictionary.

# re: WPF Localization - On-the-fly Language Selection

Tuesday, August 12, 2008 5:51 PM by Tomer Shamam

Hi inTagger again,

"The great miss of your solution (may be of Blend && VS) is impossibility of editing UI in Blend and VS designers (exception is thrown)"

This bug was fixed, so there isn't "a great miss" anymore.

Thanks

# re: WPF Localization - On-the-fly Language Selection

Tuesday, September 02, 2008 5:08 PM by Rob Burke

Thanks for this Tomer. With a few additions to this technique for convenience, I've found this really useful on a project.  Great work!  Please do keep updating this if you take any feedback on board.  Do you still use this library, or some riff on this, for your WPF localization needs?

# re: WPF Localization - On-the-fly Language Selection

Friday, September 05, 2008 11:32 AM by Celso

Hi. Thanks for this solution it´s great. But I will like to if somebody has the following problem. I have some controls on a Grid that are using a dynamic Uid, and I will like to linked its disposition at the Grid with this localization solution. So I used the following code:

<TextBlock FontSize="18">

<TextBlock.Text>

<loc:Translate Default="Text 3">

<Binding ElementName="Root" Path="Uid" />

</loc:Translate>

</TextBlock.Text>

       <Grid.Column>

               <loc:Translate Default="0">

       <Binding ElementName="Root" Path="Uid" />

</loc:Translate>

       </Grid.Column>

       <Grid.Row>

               <loc:Translate Default="3">

<Binding ElementName="Root" Path="Uid" />

</loc:Translate>

       </Grid.Row>

</TextBlock>

When I have the definition for the Row and Colum elements on the Dictionary it works fine. But when the vid property is not contain the default resulting value is not working so all the elements are being positioned at the column and row 0 of the Grid. So I will like to know what I´m doing wrong or why is this happening.

# re: WPF Localization - On-the-fly Language Selection

Sunday, September 07, 2008 2:42 PM by Tomer Shamam

Hi Rob,

Yes I'm using this solution in production. Also I know  others that are using it.

Enjoy.

# re: WPF Localization - On-the-fly Language Selection

Sunday, September 07, 2008 2:48 PM by Tomer Shamam

Hi Celso,

I would really like to help but I didn't understand what you want to do, also why you are using dynamic uid's?

Thanks

# re: WPF Localization - On-the-fly Language Selection

Saturday, October 11, 2008 5:57 PM by Ben

Hi, Tomer

I'm trying to localize a contextmenu without any success. The code that I'm curently using is the following:

<ContextMenu>

       <MenuItem>

           <MenuItem.Header>

               <loc:Translate>

                   <Binding ElementName="Root" Path="Uid" />

               </loc:Translate>

           </MenuItem.Header>

       </MenuItem>  

</ContextMenu>

After making some research I found out that the problem with this code is the fact that a contextmenu lacks of context inheritance, such as explained in this post blogs.msdn.com/.../705116.aspx. So the menuitem doesn't really knows that there is a Root element to associate the uid binding.

Do you have any suggestion in order to implement this?

Thanks

# re: WPF Localization - On-the-fly Language Selection

Thursday, October 23, 2008 9:41 PM by Tomer Shamam

Hi Ben,

Yes you are right. ContextMenu is not part of the visual tree, hence it is not supported by my solution. Maybe I will add this special support in the future. Right now, you can Bind directly to the dictionary. See what the markup extension does.

# re: WPF Localization - On-the-fly Language Selection

Tuesday, November 04, 2008 12:49 PM by Jurmerian

It lacks tooltip support.

# re: WPF Localization - On-the-fly Language Selection

Wednesday, January 21, 2009 4:51 PM by Mauro Cecili

How can i use your solution in a listView - GridViewColumn.CellTemplate with triggers? this is my case:

<GridViewColumn.CellTemplate>

 <DataTemplate>

    <Image Name="ImageTessera"/>

    <DataTemplate.Triggers>

       <DataTrigger Binding="{Binding Path=Icon}" Value="0" Loc:Translate.Uid="ChooseCardStateScaduta">

<Setter  TargetName="ImageTessera" Property="Source" Value="..\Images\TesseraELIMINATA.gif" />

<Setter   TargetName="ImageTessera" Property="ToolTip" Value="{Loc:Translate Scaduta}" />

</DataTrigger>

I try to use Loc:Translate.Uid="ChooseCardStateScaduta" <inside> setter tag but is  worong so i tried in <DataTrigger> XAML is correct but at run time i have only the default value. Can you help me?

Thnaks for your great job!!

# re: WPF Localization - On-the-fly Language Selection

Monday, January 26, 2009 9:25 PM by Marcel

Hi Tommer, thanks for your code, I'm a .Net developer starting in WPF. I used my own code based on yours so I can use my own implementation of the Dictionary.

I think your code has a great concept, wich I want to discuss with you because your comments will be very helpful.

I assume the on-the-fly update in the UI gets done because the source of the binding (in ProvideValue method of MarkupExtension inheritor) is the instance of the LanguageContext class, wich implements INotifyPropertyChanged so the users of this class be notified once it's Culture property has changed.

So my question is related with having a binding inside the content of some WPF control:

Is that(2nd paragraph) the main point of UI updating on-the-fly when language selection changes??

My question came because I used your code like this:

<Label>

     <Label.Content>

           <Translator>

                 <Binding Path={SomeProperty}/>

           <Translator>

     </Label.Content>

</Label>

and it does not work, I mean, Label does not get notified when LanguageContext.Culture has changed.

But also, like this:

<Label>

     <Label.Content>

           <Translator Key='SomeResourceKey'></Translator>

     </Label.Content>

</Label>

where 'SomeResourceKey' is a key in the resource file, it works perfect.

Why the first sample is not working?

thanks in advance

Marcel

# re: WPF Localization - On-the-fly Language Selection

Sunday, February 01, 2009 5:55 AM by Nader Alkhatib

i think with the following the URL, the original MS solution is complete with no cons (the steps involved in localization can not be thought of as cons):

www.codeproject.com/.../LocBamlClickOnce.aspx

# re: WPF Localization - On-the-fly Language Selection

Friday, February 06, 2009 2:21 PM by Tomer Shamam

Jurmerian, tooltips are natively supported, you just need to ask for it:

<TextBlock loc:Translate.Uid="3"

ToolTip="{loc:Translate}"

Text="{loc:Translate Default=Text 2}"

Background="{loc:Translate AliceBlue}"

Width="{loc:Translate 300}"

Height="{loc:Translate 30}" FontSize="18" />

# re: WPF Localization - On-the-fly Language Selection

Friday, February 06, 2009 2:35 PM by Tomer Shamam

Hi Mauro Cecili and Marcel!

Sorry for the late reply, I've upgraded the tool to version 1.3, and thanks to you I've added support for requesting any Uid decleratively.

Now you can provide Uid as part of the Translate markup extension, this will overrides any other attached Uid.

Using this feature, you can now write code like this:

<DataTemplate DataType="{x:Type local:Data}">

  <DataTemplate.Triggers>

     <DataTrigger Binding="{Binding Path=ID}" Value="1">

        <Setter Property="ToolTip"

                Value="{loc:Translate Uid=11, Default=Apple}" />

     </DataTrigger>

     <DataTrigger Binding="{Binding Path=ID}" Value="2">

 <Setter Property="ToolTip"

                 Value="{loc:Translate Uid=12, Default=Bannana}" />

     </DataTrigger>

     <DataTrigger Binding="{Binding Path=ID}" Value="3">

         <Setter Property="ToolTip"

                 Value="{loc:Translate Uid=13, Default=Melon}" />

     </DataTrigger>

  </DataTemplate.Triggers>

</DataTemplate>

Cheers!

# re: WPF Localization - On-the-fly Language Selection

Tuesday, March 10, 2009 9:49 AM by Abraham Mathew

Hi,

  Thank you for your code for localization.I am trying to port your demo code to a WPF Project we have to implement localization support for multiple languages,I have defined two xml files:

1.en-US.xml

2.ar-KW.xml

--------------------------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>

<Dictionary EnglishId="Arabic" CultureId="Arabic" Culture="ar-KW">

<Value Id="Active" Content="مُفعل"/>

</Dictionary>

--------------------------------------------------------------------------------

<?xml version="1.0" encoding="utf-8" ?>

<Dictionary EnglishId="English" CultureId="English" Culture="en-US">

<Value Id="Active" Content="Active"/>

</Dictionary>

--------------------------------------------------------------------------------

Issue is that when I load the Arabic file from \Languages folder of my app the

app freezes,but when I rename the en-US.xml file to ar-KW.xml file there is

no issues (but english is shown).

I just use the library to read the current value of the title and change

it to the local value and fill a field name of a grid property.

LanguageDictionary.RegisterDictionary(CultureInfo.GetCultureInfo("ar-KW"), new XmlLanguageDictionary("Languages/ar-KW.xml"));

LanguageContext.Instance.Culture = CultureInfo.GetCultureInfo("ar-KW");

try {

   column.Title = LanguageDictionary.Current.Translate<string>(fieldLayoutInfo.Title, "Content");

} catch (Exception ex) {

   throw (ex);

}

Is there any encoding that I have to follow when I create my xml file ?

Any suggestions would be helpfull

Thanks

# re: WPF Localization - On-the-fly Language Selection

Tuesday, March 10, 2009 10:52 PM by Tomer Shamam

Hi Abraham,

It looks like you have problems with XmlDocument and not WPF.

# re: WPF Localization - On-the-fly Language Selection

Monday, May 18, 2009 5:54 PM by Arthur

Hello Tomer,

First I would like to thank you for this usefull piece of code.

Hope you could help me with the following problem;

When I try to use it in a resource dictionary it works, but Blend 2.5 gives me the error "The ':' characher, hexadecimalvalue 0x3A, cannot be included in a name. Line...". Visual studio does not give this error. Also running the app is no problem.

# re: WPF Localization - On-the-fly Language Selection

Monday, May 25, 2009 8:54 AM by Tomer Shamam

Arthur, did you try it on Blend 2.0 Or 3.0 preview?

2.5 is kind of deprecated.

# re: WPF Localization - On-the-fly Language Selection

Wednesday, June 03, 2009 11:51 AM by Yuval

Hi Tomer,

I'm from AVT, and participated in your course on WPF.

As you know, we use your localization module in our software.

It's been modified through time, but the basics are the same.

There is that bug in version 1.0 where you cannot open the designer. You fixed it in version 1.2 and that's great.

We want to fix it in our code also.

Unfortunatelly, I cannot spot the bug fix among all your changes for version 1.2.

Can you help me with that? Can you refer me to the exact code change that fixes the bug?

Thanks.

# re: WPF Localization - On-the-fly Language Selection

Wednesday, June 03, 2009 10:46 PM by realmontanakid

Is it possible to pass a vid in xaml? What you did with "NotEnoughMemory" and "Message". Could it work from Xaml code?

Kind regards

# re: WPF Localization - On-the-fly Language Selection

Monday, June 08, 2009 9:10 AM by Tomer Shamam

Hi Yuval,

Unfortunately I don't remember what the change was so please download version 1.1 and 1.2 and compare both using WinDiff for example.

# re: WPF Localization - On-the-fly Language Selection

Friday, August 14, 2009 2:33 AM by Anon

This sample project was just what I needed to enable my users to select a language on the fly.  Seems to work well.  Thanks for sharing your expertise, Tomer!

# re: WPF Localization - On-the-fly Language Selection

Friday, August 14, 2009 8:42 AM by Tomer Shamam

You welcome!

# re: WPF Localization - On-the-fly Language Selection

Thursday, August 20, 2009 1:45 PM by Arthur

Hi Tomer,

I try to have a TextBlock in a datatemplate translated. The TextBlock is not bound to any data. Whatever I try, I cannot get the textblock to translate.

Then I started to modify your sample app to see if it would work there. I modified the DataTemplate (a stackpanel wuth the orgininal contents plus  TextBlock loc:Translate.Uid="20" Foreground="Green" Text="{loc:Translate}"

It al works fine, but when I start your MainWindow from another window (and make that window the startup window) it fails to translate this TextBlock as well.

How to solve this??

Best regards,

Arthur

# re: WPF Localization - On-the-fly Language Selection

Sunday, September 13, 2009 4:21 PM by John

Which license applies to the files?

# re: WPF Localization - On-the-fly Language Selection

Sunday, September 13, 2009 10:19 PM by Tomer Shamam

Hi John,

You may use it freely, just add credits.

Thanks,

Tomer

# re: WPF Localization - On-the-fly Language Selection

Sunday, September 20, 2009 1:19 PM by Chris

Hallo everybody,

I have problems with Blend 3. My Code looks like this:  ....loc:Translate.Uid="EntryWindow_Btn1_DataHandling" Text="{loc:Translate Default=Type}".

This works, but if i try to edit the 'Default = Type1' -Property (in Blend 3), i get an Exception (.. for the Translate-Type, there is no DependencyObjectType (Default)-Element available. In the Code we have an normal Property Default(get;set) maybe this is the problem.

Anybody has an idea.

Thanks,

Chris

# re: WPF Localization - On-the-fly Language Selection

Tuesday, May 18, 2010 1:51 PM by Yannick

Hi all,

I'm trying to set a tooltip on a button in a DataGridTemplateColumn,

I tried a lot but either it gives a runtime error or it uses the default value:

something like this:

<DataGridTemplateColumn x:Name="dataGridMainPatientsOverviewEditColumn" Width="23">

<DataGridTemplateColumn.CellTemplate>

 <DataTemplate>

  <Button x:Name="buttonMainPatientsOverviewEditItem" loc:Translate.Uid="buttonMainPatientsOverviewEditItem" BorderThickness="0" Style="{StaticResource styleEditRowButton}" Click="buttonMainPatientsOverviewEditItem_Click">

   <Button.ToolTip>

    <loc:Translate Default="Edit a patient">

     <Binding ElementName="dataGridMainPatientsOverview" Path="Uid" />

    </loc:Translate>

   </Button.ToolTip>

   <!--<Button.ToolTip>

    <loc:Translate Uid="dataGridMainPatientsOverviewToolTip" Default="Edit a patient">

     <Binding Path="Uid" />

    </loc:Translate>

   </Button.ToolTip>-->

   <!--<Setter Property="ToolTip" Value="{loc:Translate ToolTip, Uid=buttonMainPatientsOverviewEditItemToolTip, Default=''}" />-->

  </Button>

 </DataTemplate>

</DataGridTemplateColumn.CellTemplate>

</DataGridTemplateColumn>

anyone can help me with this ?,

thanks

# re: WPF Localization - On-the-fly Language Selection

Tuesday, May 18, 2010 2:11 PM by Yannick

handy addition

Using direct translation returns null if the value is not found,

therefore I added the following method in "LanguageDictionary.cs" so default values can be used:

public TValue Translate<TValue>(string uid, string vid, object defaultValue)

{

  return (TValue)Translate(uid, vid, defaultValue, typeof(TValue));

}

# re: WPF Localization - On-the-fly Language Selection

Wednesday, July 21, 2010 3:57 PM by Ed

Hi Tomer, thank you for taking the time to do this. It looks precisely like the solution I need to implement and so could save me hours.

# re: WPF Localization - On-the-fly Language Selection

Thursday, July 22, 2010 12:09 AM by Tomer Shamam

You welcome Ed, it's my pleasure.

# re: WPF Localization - On-the-fly Language Selection

Wednesday, August 25, 2010 1:05 AM by Isaac

Big thanks for the approach , VERY COOOOOOOL !!!! Like it !!! And will use it for each of my projects

# re: WPF Localization - On-the-fly Language Selection

Wednesday, August 25, 2010 9:54 AM by Tomer Shamam

Enjoy, my Pleasure ;)

# re: WPF Localization - On-the-fly Language Selection

Monday, November 01, 2010 3:53 PM by Saragani

Hi, it will be good if I can address a specific property in the XML (Right now it goes to the property with the name like the property in the Control).

This is good when the same text is used in several places, for example a TextBlock and a Lable (while one of them has Text and the other Content).

The Dynamic Uid idea is good but to excellent.

I was hoping to be able to do:

<TextBlock loc:Translate.Uid="{Binding Name}" />

but GetUid(_target) returns an empty string.

Why would I want to do that?? Because a user control that is Binded to a DataContext (in this case a ViewModel) have several properties to show in the UI, for example:

<TextBlock loc:Translate.Uid="{Binding Name}" />

<TextBlock loc:Translate.Uid="{Binding Description}" />

<Button loc:Translate.Uid="{Binding ButtonText}" />

You might suggest the idea of having the dynamic Uid in the template and having the properties in the XML, but if I need that each of the textboxes and the buttons will also have a tooltip then it makes the XML huge.

Any way to achieve what I want?

# re: WPF Localization - On-the-fly Language Selection

Friday, January 14, 2011 10:22 AM by dkl

When you use this in .NET 4.0, you are likely to encounter weird exceptions when using both styles of setting Uid (attached property and inside markup extension) at the same time.

Solution is simple: Rename one of the properties. In .NET 4.0 it is not possible to have regular property and dependency property of the same name.

# re: WPF Localization - On-the-fly Language Selection

Tuesday, January 18, 2011 6:31 PM by drf

dkl, I'm not sure I understand. Which properties have the same name?

Thanks.

# re: WPF Localization - On-the-fly Language Selection

Tuesday, May 03, 2011 12:06 PM by Exception Handler

Thanks for your post.. I have done the same in my project I have added reference of your dll file, and have created the same folder Languages and inside this I have two xml files..

when i run the application its save file not found...

can you please explain what i am doing wrong here,,

Regards

# re: WPF Localization - On-the-fly Language Selection

Tuesday, May 03, 2011 10:25 PM by Tomer Shamam

Hi Exception Handler,

If you could send me a prototype of your project, I'll be happy to fix this for you.

Tomer

# re: WPF Localization - On-the-fly Language Selection

Wednesday, May 04, 2011 11:23 AM by Exception Handler

I have added a value for tooltip and text in en-US.xml as follow

<Value Id ="7" Text ="Edit" ToolTip="Edit this Record"/>

and then this applies on the below code,. The ToolTip is not working here

but the Image Source is working,, means it is getting imagepath

from en-US.xml

What I am doing wrong here

<my:DataGridTemplateColumn  Visibility="Visible"     Header=""

IsReadOnly="True" Selector.IsSelected="True" >

                   <my:DataGridTemplateColumn.CellTemplate>

<DataTemplate >

  <Label  >

  <Hyperlink  Name="hpEdit" Click="hpEdit_Click">

  <Hyperlink.Style>

  <Style TargetType="{x:Type Hyperlink}">

<Setter Property="TextBlock.TextDecorations" Value="{x:Null}" />

</Style>

</Hyperlink.Style>

<WrapPanel>

<TextBlock loc:Translate.Uid="7"  Text="{loc:Translate Content}" ></TextBlock>

<Image   Height="20" Name="ImgEdit"

loc:Translate.Uid="8"  Source="{loc:Translate Source}"  />

</WrapPanel>

</Hyperlink>

</Label>

</DataTemplate>

</my:DataGridTemplateColumn.CellTemplate>

</my:DataGridTemplateColumn>

Regards

# re: WPF Localization - On-the-fly Language Selection

Wednesday, May 04, 2011 11:25 AM by Exception Handler

I have added a value for tooltip and text in en-US.xml as follow

<Value Id ="7" Text ="Edit" ToolTip="Edit this Record"/>

and then this applies on the below code,. The ToolTip and Text is not

working here ,, means not getting values from en-US.xml

but the Image Source is working,, means it is getting imagepath

from en-US.xml

What I am doing wrong here

<my:DataGridTemplateColumn  Visibility="Visible"     Header=""

IsReadOnly="True" Selector.IsSelected="True" >

                   <my:DataGridTemplateColumn.CellTemplate>

<DataTemplate >

  <Label  >

  <Hyperlink  Name="hpEdit" Click="hpEdit_Click">

  <Hyperlink.Style>

  <Style TargetType="{x:Type Hyperlink}">

<Setter Property="TextBlock.TextDecorations" Value="{x:Null}" />

</Style>

</Hyperlink.Style>

<WrapPanel>

<TextBlock loc:Translate.Uid="7"  Text="{loc:Translate Text }

ToolTip="{loc:Translate ToolTip}" ></TextBlock>

<Image   Height="20" Name="ImgEdit"

loc:Translate.Uid="8"  Source="{loc:Translate Source}"  />

</WrapPanel>

</Hyperlink>

</Label>

</DataTemplate>

</my:DataGridTemplateColumn.CellTemplate>

</my:DataGridTemplateColumn>

Regards

# re: WPF Localization - On-the-fly Language Selection

Wednesday, May 04, 2011 9:10 PM by Tomer Shamam

Hi Exception Handler,

You provided two versions of your code, so I'll try to target the latest one.

First you don't need to write ToolTip="{loc:Translate ToolTip}", just write ToolTip="{loc:Translate}". The markup extension already knows that it activated on the ToolTip property.

Second, in the Text="{loc:Translate Text }, it looks like you've added additional space after “Text”, try to remove it since XAML parser think that it should be 'Text '.

As for the tooltip, have no clue. Did you spell it correctly?

Feel free to send me a code sample.

Tomer

# re: WPF Localization - On-the-fly Language Selection

Tuesday, May 10, 2011 10:04 PM by ef

Hi,

Great solution!

How can I pass arguments to {0} and {1} etc when I bind programmatically?

I bind like this, to add text to a button:

Binding binding = new Binding("Dictionary");

binding.Source = LanguageContext.Instance;

binding.Converter = new LanguageConverter(uid, "Text", text);

BindingOperations.SetBinding(aButton, Button.ContentProperty, binding);

Any help is much appreciated!

Regards

# re: WPF Localization - On-the-fly Language Selection

Sunday, May 15, 2011 5:07 PM by Exception Handler,

I have a WPF brower base Application.The file not found error  on

LanguageDictionary.RegisterDictionary(

               CultureInfo.GetCultureInfo("en-US"),

               new XmlLanguageDictionary("Languages/en-US.xml"));

.. How can i email you my source code ?

# re: WPF Localization - On-the-fly Language Selection

Monday, May 16, 2011 4:54 PM by Fabio Alves

Blend gives me an error:

The name "Translate" does not exist in the namespace "schemas.tomer.com/.../presentation".

Is there a new website hosting the xml schema?

# re: WPF Localization - On-the-fly Language Selection

Wednesday, May 18, 2011 11:39 AM by Tomer Shamam

Hi Fabio,

What version of Blend are you using?

this "schema" doesn't related to the web at all. It's just a unique string I defined as an assembly attribute "XmlnsNamespaceAttribute", and it's defined in the AssemblyInfo.cs file.

# re: WPF Localization - On-the-fly Language Selection

Wednesday, May 18, 2011 11:42 AM by Tomer Shamam

Exception Handler, Hi again ;)

Working with XBAP application, the runtime directory is different than a regular app (security reasons). In that case, you should have the dictionary XML in the working directory. You may also try working with Isolated Storage.

# re: WPF Localization - On-the-fly Language Selection

Tuesday, November 08, 2011 5:48 PM by Melianos

Hello, i'm using your translation mechanism, all works fine but i strongly need one improvement which is : allow uid to accept binding so that i can bind to some values when using mvvm.

e.g : {{loc:Translate Uid={Binding Path=ViewModelProperty}}

Any help on this ?

Thx

Thanks

# re: WPF Localization - On-the-fly Language Selection

Tuesday, May 29, 2012 5:17 PM by OneOfYourFan

Hi Tomer!

I'm delighted with your solution. I tried recompiling the Localization project and Demo application using .NET 4 Client Profile and when I run it, I get a run-time error: "Object of type 'Tomers.WPF.Localization.Translate' cannot be converted to type 'System.Windows.DependencyObject'.".

I pinpointed the problem to the setter in the Data Trigger:

<Setter Property="ToolTip" Value="{loc:Translate Uid=1, Default=Apple}" />

Any idea what can be the fix? The Translate class already inherits MarkupExtension, so it cannot also derive from DependencyObject...

# re: WPF Localization - On-the-fly Language Selection

Tuesday, May 29, 2012 5:24 PM by OneOfYourFan

Hi Tomer!

I'm delighted with solution except for one point. I tried recompiling it with .NET 4 Client Profile and it gave me run-time argument exception: "Object of type 'Tomers.WPF.Localization.Translate' cannot be converted to type 'System.Windows.DependencyObject'.".

The line in cause is:

<Setter Property="ToolTip" Value="{loc:Translate Uid=1, Default=Apple}" />

I don't see how to solve the issue as the Translate class already inherits class MarkupExtension, so it cannot also derive from Dependency Object.

Any help would be welcome.

# re: WPF Localization - On-the-fly Language Selection

Sunday, June 03, 2012 12:32 AM by Tomer Shamam

It's something with the "Trigger" inside the DataTemplate.

As I don't have the time to investigate it, please remove the triggers, if you don't use this solution inside a trigger:

<DataTemplate.Triggers>

<DataTrigger Binding="{Binding Path=ID}" Value="1">

<Setter Property="ToolTip" Value="{loc:Translate Uid=11, Default=Apple}" />

</DataTrigger>

<DataTrigger Binding="{Binding Path=ID}" Value="2">

<Setter Property="ToolTip" Value="{loc:Translate Uid=12, Default=Bannana}" />

</DataTrigger>

<DataTrigger Binding="{Binding Path=ID}" Value="3">

<Setter Property="ToolTip" Value="{loc:Translate Uid=13, Default=Melon}" />

</DataTrigger>

</DataTemplate.Triggers>

# re: WPF Localization - On-the-fly Language Selection

Thursday, October 25, 2012 9:43 AM by Artholl

Hi,

I want to thank you for your extension. It's great.

I have one issue and it was really helpfull if you can help me.

In my WPF app I set some text onto Slider buttons and I do this in App.xaml. Is there any possibility to translate this text? Because if I do this as normal it doesn't work...

Thank you for your advice.

# re: WPF Localization - On-the-fly Language Selection

Thursday, December 06, 2012 11:28 AM by Geerten

Hi Tomer Shamam,

Thanks for your solution, it's very nice and elegant, I like it!

However, while converting my XAML files to be localizable, I encountered an error.

I have the following ItemsControl:

<ItemsControl ItemsSource="{Binding DisplayCameras}" >

  <ItemsControl.ItemsPanel>

     <ItemsPanelTemplate>

        <UniformGrid Rows="1" Height="30" />

     </ItemsPanelTemplate>

  </ItemsControl.ItemsPanel>

  <ItemsControl.ItemTemplate>

      <DataTemplate>

          <Button Content="{loc:clsTranslate Key=txtCameraDisplayName}" />

      </DataTemplate>

  </ItemsControl.ItemTemplate>

</ItemsControl>

But when I execute this, the software just hangs! And I can't figure out what is causing it.

If I change the button to:

 <Button loc:clsTranslate.Key="txtCameraDisplayName2" Content="{loc:clsTranslate}" />

It shows the buttons, but without the content..

Could you help with this?

Thanks in advance.

Best regards,

Geerten

# re: WPF Localization - On-the-fly Language Selection

Monday, December 10, 2012 10:36 AM by Geerten

Oh, and btw:

I renamed your Uid property to Key.

Best regards,

Geerten

# re: WPF Localization - On-the-fly Language Selection

Wednesday, February 06, 2013 2:00 PM by Yves

Hi Tomer,

could you please explain how this all works? I'm trying to do something similar and create a MarkupExtension that can translate arbitrary, specified text keys into strings, but also regards a specified counting value to use specialised translations. Like "one day" but "4 days". This count parameter must be bindable because it can change.

I've tried to follow your code, starting in the TranslateExtension.BindDictionary method, but I can't follow it anywhere. It returns a BindingExpression instance and that's all, and it seems to work. Is it understandable what your code does and why it works? How did you find out about it all?

I haven't even tried to understand the MultiBinding part yet, though it looks interesting.

# re: WPF Localization - On-the-fly Language Selection

Wednesday, March 20, 2013 11:00 AM by Pragya

While loading german language file, we are getting following exception :

'Schließen' is an unexpected token. Expecting white space. Line 455, position 108.

Following is the snippet from 'de-DE.xml'

<Value Id="msgExit" Text="Schließen" />

The encoding of the xml is UTF-8 only.

Requesting you suggest something for this problem.

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems