6
votes

I'm creating a multi-language application with WPF. I'm using static resources, strings stored in .resx/res files to have text appear in the culture of the user.

Here's a part of the project's directory structure:

  • Resources
    • GreetingWindowRes.resx (this is the default, for en-US)
    • GreetingsWindowRes.de-DE.resx

In the .csproj, I have: <UICulture>en-US</UICulture>

In the AssemblyInfo.cs: [assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]

After compilation, I can see the resource files appear:

  • en-US / MyApp.resources.dll
  • de-DE / MyApp.resources.dll

So I bind to a static string resource in GreetingWindow.xaml:

<windows:MyWindowBase x:Class="CommanderDotNET.MyApp.Windows.GreetingWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:windows="clr-namespace:MyApp.Windows"
    xmlns:res="clr-namespace:MyApp.Resources">

    <Label Content="{x:Static res:GreetingWindowRes.FirstGreetingText}" />

</windows:MyWindowBase>

The results are puzzling to me:

  1. If UICulture is set to de-DE, the label text appears correctly in German.
  2. If UICulture is set to en-US, System.Windows.Markup.StaticExtension throws a XamlParseException. The error I see for the XAML must be the reason:

Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "MyApp.Resources.GreetingWindowRes.en-US.resources" was correctly embedded or linked into assembly "MyApp" at compile time, or that all the satellite assemblies required are loadable and fully signed.

What am I doing wrong?

SOLUTION:

After lots of searching, I found a good explanation here: http://www.west-wind.com/weblog/posts/2009/Jun/04/Resx-and-BAML-Resources-in-WPF

Apparently when using UltimateResourceFallbackLocation.Satellite + <UICulture>, you would need to have both ResxResource.resx and GreetingWindowRes.en-US.resx files for the main language (nasty duplication).

But, if you only want to use Resx resources, and no BAML localization, this is not the way to go, and the situation is a lot better. The proper way with only Resx resources:

  • AssemblyInfo.cs: [assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
  • .csproj: do NOT add <UICulture>
  • resource naming: ResxResource.resx (main language) + ResxResource.de-DE.resx (additional language)
1
Thanks for the explanation :)sexta13

1 Answers

3
votes

I think that when you set an UICulture you must have the corresponding resx file. So, To solve your problem you must create a file for en-US culture (that will be the same as Resources.resx).

I think (but I can be wrong) that the Resources.resx is used for the default culture, or the culture that the PC has.