XAMLMarkupExtensions/WPFLocalizeExtension

Support for a fallback assembly

qmatteoq opened this issue · 7 comments

Hello, I'm trying to implement a scenario with the WPF Localization Extension, but I can't find a way to do it, so I wanted to check if it's indeed a missing feature or if there's any workaround.
Here is my scenario, based on an application which is distributed to multiple customizers, who can require a specific customization of the base app.

  1. I have a basic .resx file, one for each language, with the various strings' translations
  2. Some customers, for some languages, may require a slightly different translation than the standard one for some labels.

My goal, as such, would be to provide to the application a basic .resx file and then, for the same language, provide another one with the same keys (not all of them, just a few) that should override the basic localization.
I tried to implement this scenario by setting the ResxLocalizationProvider.DefaultAssembly property directly to the controls that must support this scenario and to include the customized resources files in a separate class library. However, the problem is that I don't see a way to specify a "Fallback assembly" to use in case the resource isn't present in the customized resource file.

My goal would be to achieve something like "as first priority, take the resource from the custom resource file but, if the key isn't available, fallback to the basic one I've specified for the whole Windows / Page / UserControl".

Is there a way to satisfy this scenario with the current implementation?

Thanks!

Hello!
I think the easiest way now - use LocalizeDictionary.Instance.MissingKeyEvent. When you handle this event you can try find missing key in your default .resx file.
Here sample of usages

Thanks for the suggestion! I thought about this as well, but I'm not able to get the MissingKeyEvent to work properly. I tried to match my project with the sample one, but I can't really understand what's going on.
This is what I'm doing.

I've setup the main Window of the app like this:

lex:ResxLocalizationProvider.DefaultAssembly="ModernWpfDemo"
lex:ResxLocalizationProvider.DefaultDictionary="Strings"
lex:LocalizeDictionary.DesignCulture="it"

Then, in the code behind, I have the following code:

public MainWindow()
{
    InitializeComponent();
    LocalizeDictionary.Instance.OutputMissingKeys = true;
    LocalizeDictionary.Instance.MissingKeyEvent += Instance_MissingKeyEvent;
}

private void Instance_MissingKeyEvent(object sender, MissingKeyEventArgs e)
{
    Debug.WriteLine(e.Key);
    e.MissingKeyResult = "Hello World";
}

Then, I have a Button control in the page which points to my custom assembly:

<Button lex:ResxLocalizationProvider.DefaultAssembly="ModernWpfDemo.LocalOverride" 
        Grid.Column="1" 
        Grid.Row="1" 
        FontSize="18" 
        Margin="5" 
        Content="{lex:Loc}" 
        x:Name="btnChangeLanguage" 
        Click="OnChangeLanguage" />

The ModernWpfDemo.LocalOverride contains another Strings.resx file, where the key btnChangeLanguage_Content is missing.
However, when the application starts, the Instance_MissingKeyEvent isn't raised. Only when I press the button in question (which is without any label), the event is triggered, but all the properties of MissingKeyEventArgs object are missing (e.g. the Key property, which I would need to do the lookup, is null).

Overall, the whole behavior is quite strange. I've tried also to change another TextBlock control to manually point to a key that doesn't exist:

 <TextBlock x:Name="txtLatitude" Text="{lex:Loc Key=Test}" FontSize="18" Margin="10"/>

The outcome is that, in my window, I see a TextBlock with text "Key: Test", while I would have expected to see the MissingKeyEvent being triggered.

image

Do you have any idea what am I missing?

Please, in MainMenu move InitializeComponent after the subscription. The problem is that all event generated before subscription.
Probably moving this subscription to App.xaml.cs, OnStartup method is better way.

About Button. You do not spicife key in yours Content="{lex:Loc}" . Is it OK?

About Button. You do not spicife key in yours Content="{lex:Loc}" . Is it OK?

Yes, this is OK. But unfortunetly MissingKeyEvent passes only original key. I'm not sure if it's possible to fix this behavior, because it tryes find both {ControlName}_{ControlProperty} and {ControlName} and it will hard to understand which key we should pass in this case.

Thanks @Karnah , by moving the InitializeComponent() after the subscription I've been able to fix the first problem.
Regarding the second, do you mean that currently that using the Loc markup extension without specifying a key doesn't trigger the MissingKeyEvent? Yeah this is what I'm seeing as well. But it isn't a big deal, I'm ok also with forcing a key if it can help to solve my scenario.

I will do some more experiment tomorrow. Thanks a lot for your help!

You are always welcome :)

I think there is another way to solve this issue - create your own ILocalizationProvider. But it seems to me it will not be so easy.

@qmatteoq, do you have any other questions or this issue can be closed? :)