0

My Scenario:

MainWindow with SplitView and several Pages, each containing Labels, Buttons and Tabs. I'm using the MVVM pattern, now I want to be able to change the language at run time using e.g. a ComboBox. The language keys should be read from an external file e.g. an .mdb-file, that is because it should be possible to change the description of some buttons after compilation.

I was already reading a lot, most of the time they used resource-files or didn't follow the MVVM pattern. The closest I found was this.

Here I'm facing four problems:

  1. They use the code-behind of the MainWindow to set the DataContext, mine is already used for the Menu :/
  2. The text in my Labels/Buttons should be changed on several Pages, how do I do this?
  3. I generate some content of the menus in my ViewModel, how to use here the language keys from the file? I can not bind them like in the XAML?
  4. There is no option to choose which language setting should be applied. (this I might be able to figure out as soon as I know that the concept is worth to pursue at all)

I'm new to MVVM and C#, so I'm not yet very familiar with the thinking in MVVM pattern, but I hope that you can help me to find a solution:)

Edit: The linked question did not solve my problem because it does not fulfill my need for language files that are stored externally and can be modified and read in during run time. Altough it's a very good approach which I'll use when I don't need to modify the language files externally:)

Berger
  • 299
  • 3
  • 13
  • Possible duplicate of [Best way to implement multi-language/globalization in large .NET project](https://stackoverflow.com/questions/373388/best-way-to-implement-multi-language-globalization-in-large-net-project) – JMK Nov 06 '19 at 09:09
  • I think there is sufficient difference in this question it is not really a duplicate. I also think there's an obvious omission from the list. – Andy Nov 06 '19 at 10:46

2 Answers2

1

Please read linked article again, it seems you don't understand principle of why and how it works.

They use the code-behind of the MainWindow to set the DataContext, mine is already used for the Menu :/

You don't have to set DataContext. The bindings in xaml utilize indexer in view model. You can add indexer to your view model or (better) simply add property returning instance of StringResourceReader, then all localizable bindings will become

<TextBlock ... Text="{Binding PropertyName[TESTSTRING]}"/>

The text in my Labels/Buttons should be changed on several Pages, how do I do this?

See above. All view models should either have indexer or property.

Alternatively you can have static property somewhere and bind to it instead of changing each and every view model. But that would make binding syntax in xaml longer.

I generate some content of the menus in my ViewModel, how to use here the language keys from the file? I can not bind them like in the XAML?

In code behind just call rm.GetString(name) directly.

There is no option to choose which language setting should be applied. (this I might be able to figure out as soon as I know that the concept is worth to pursue at all)

_fileName is language. Different files are different localizatons. It's up to you how you organize which file is which language. E.g. you can use two letters somewhere in file name to identify language easier.

Sinatr
  • 20,892
  • 15
  • 90
  • 319
1

WPF has Resource Dictionaries which work well for this.

If you merge these in app.xaml their values go into application.current.resources.

This is a sort of hashtable which is then available throughout your application.

You can merge uncompiled .xaml resource dictionaries using the same sort of syntax.

As explained:

https://social.technet.microsoft.com/wiki/contents/articles/28797.wpf-dynamic-xaml.aspx#Loading_a_Flat_File_as_a_Resource_Dictionary

That Dictionary1.xaml being merged is an uncompiled flat file that could potentially be replaced or edited.

You can reference a keyed resource using {staticresource keyname} or {dynamicresource keyname}.

What's the difference between StaticResource and DynamicResource in WPF?

If you make all your text values you wish to switch out string resources in a flat uncompiled .xaml resource dictionary then you can reference them in xaml.

Use dynamicresource and should the resource be changed you will get the new value appear in your textblock or label.

Thus similar to this link:

https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/how-to-use-a-resourcedictionary-to-manage-localizable-string-resources

Do this with your app, compile and deliver a .xaml file along with your distributable. The user sees the strings out that.

Copy a new .xaml file over that resource dictionary.

The user will then see the values out that file.

Edit the file in notepad and change a value.

When the app starts up again it will get the new value.

You can also overlay values with new ones have the same key.

Thus you can have an original values resource dictionary compiled in.

Give them an uncompiled copy.

Your code merges both with that uncompiled copy last.

If they edit it or replace it they get the new values.

If it all goes horribly wrong somehow they can empty the entire contents of the uncompiled resource dictionary between the dictionary tags. They then revert to the original values.

You can also have multiple layers for branding and localisation and merge different iconography as well as strings.

Say you wanted to control strings and whatnot without user interaction.

You could host your customised files on a web site.

Download the file from a server into appdata and merge from there in code.

Or you can store strings in a database, xamlreader.parse into a resource dictionary you merge.

I've used variations of the approach successfully on several projects.

Andy
  • 11,864
  • 2
  • 17
  • 20
  • This solution seems also to be interesting, thanks! But as I already implemented the other way, I'd like to give it a try first:) – Berger Nov 07 '19 at 06:44
  • At the end I used your approach, it was just a few lines of code and super easy to understand in comparison to the other approach. Additionally I can even do everything I wanted like switching the language at run time, modifying the external XAML-file and when I reload it during run time I see the changes immediately. Accessing the values in C# code is also easy using FindRessource(), perfect! – Berger Nov 12 '19 at 04:58