- 1. Usage in XAML.
- 2. Usage in code.
- 3. ErrorHandling.
- 4. Validate.
- 5. FormatString.
- 6. LanguageSelector
The library has a StaticExtension
markupextension that is used when translating.
The reason for naming it StaticExtension
and not TranslateExtension
is that Resharper provides intellisense when named StaticExtension
Binding the text like below updates the text when Translator.EffectiveCulture
changes enabling runtime selection of language.
The markupextension has ErrorHandling = ErrorHandling.ReturnErrorInfo as default, it encodes errors in the result, see ErrorFormats)
<Window ...
xmlns:p="clr-namespace:Gu.Wpf.Localization.Demo.WithResources.Properties"
xmlns:l="http://gu.se/Localization">
...
<TextBlock Text="{l:Static p:Resources.SomeResource}" />
<TextBlock Text="{l:Enum ResourceManager={x:Static p:Resources.ResourceManager},
Member={x:Static local:SomeEnum.SomeMember}}" />
...
The above will show SomeResource in the Translator.EffectiveCulture
and update when culture changes.
<Grid l:ErrorHandling.Mode="ReturnErrorInfo"
... >
...
<TextBlock Text="{l:Static p:Resources.SomeResource}" />
<TextBlock Text="{l:Enum ResourceManager={x:Static p:Resources.ResourceManager},
Member={x:Static local:SomeEnum.SomeMember}}" />
...
By setting the attached property ErrorHandling.Mode
we override how translation errors are handled by the StaticExtension
for the child elements.
A markupextension for accessing Translator.EffectiveCulture
from xaml. Retruns a binding that updates when EffectiveCulture changes.
<Grid numeric:NumericBox.Culture="{l:EffectiveCulture}"
... >
...
<StackPanel Orientation="Horizontal">
<TextBlock Text="Effective culture: " />
<TextBlock Text="{l:EffectiveCulture}" />
</StackPanel>
...
Get or set the current culture. The default is null
Changing culture updates all translations. Setting culture to a culture for which there is no translation throws. Check ContainsCulture() first.
Get or set the current culture. The default is null
Changing culture updates all translations. Setting culture to a culture for which there is no translation throws. Check ContainsCulture() first.
Get the culture used in translations. By the following mechanism:
- CurrentCulture if not null.
- Any Culture in matching by name.
- Any Culture in matching by name.
- CultureInfo.InvariantCulture When this value changes EffectiveCultureChanged is raised and all translatins updates and notifies.
Get a list with the available cultures. Cultures are found by looking in current directory and scanning for satellite assemblies.
Get or set how errors are handled. The default value is ReturnErrorInfoPreserveNeutral
.
Translate a key in a ResourceManager.
Use global culture & error handling:
Translator.CurrentCulture = CultureInfo.GetCultureInfo("en"); // no need to set this every time, just for illustration purposes here.
string inEnglish = Translator.Translate(Properties.Resources.ResourceManager,
nameof(Properties.Resources.SomeResource));
string neutral = Translator.Translate(Properties.Resources.ResourceManager,
nameof(Properties.Resources.SomeResource),
CultureInfo.InvariantCulture);
string inSwedish = Translator.Translate(Properties.Resources.ResourceManager,
nameof(Properties.Resources.SomeResource),
CultureInfo.GetCultureInfo("sv"));
Translator.ErrorHandling = ErrorHandling.ReturnErrorInfo; // no need to set this every time, just for illustration purposes here.
string inSwedish = Translator.Translate(Properties.Resources.ResourceManager,
nameof(Properties.Resources.SomeResource),
ErrorHandling.Throw);
Translator.ErrorHandling = ErrorHandling.Throw; // no need to set this every time, just for illustration purposes here.
string inSwedish = Translator.Translate(Properties.Resources.ResourceManager,
nameof(Properties.Resources.SomeResource),
ErrorHandling.ReturnErrorInfo);
Translator.CurrentCulture = CultureInfo.GetCultureInfo("en");
string inSwedish = Translator.Translate(Properties.Resources.ResourceManager,
nameof(Properties.Resources.SomeResource__0__),
foo);
Same as translator but used like Translator<Properties.Resources>.Translate(...)
An object with a Translated property that is a string with the value in Translator.EffectiveCulture
Implements ÌNotifyPropertyChangedand notifies when
Translator.EffectiveCulture` changes.
Translation translation = Translation.GetOrCreate(Properties.Resources.ResourceManager, nameof(Properties.Resources.SomeResource))
When calling the translate methods an ErrorHandling argument can be provided.
If ErrorHandling.ReturnErrorInfo
is passed in the method does not throw but returns information about the error in the string.
There is also a property Translator.ErrorHandling
that sets default behaviour. If an explicit errorhandling is passed in to a method it overrides the global setting.
By setting Translator.Errorhandling
the global default is changed.
When ReturnErrorInfo
or ReturnErrorInfoPreserveNeutral
is used the following formats are used to encode errors.
Error | Format |
---|---|
missing key | !{key}! |
missing culture | ~{key}~ |
missing translation | _{key}_ |
missing resources | ?{key}? |
invalid format | {{"{format}" : {args}}} |
unknown error | #{key}# |
Conveience API for unit testing localization.
Validate a ResourceManager
like this:
TranslationErrors errors = Validate.Translations(Properties.Resources.ResourceManager);
Assert.IsTrue(errors.IsEmpty);
Checks:
- That all keys has a non null value for all cultures in
Translator.AllCultures
- If the resource is a format string like
"First: {0}, second{1}"
it checks that.- The number of format items are the same for all cultures.
- That all format strings has format items numbered 0..1..n
Validate an enum
like this:
TranslationErrors errors = Validate.EnumTranslations<DummyEnum>(Properties.Resources.ResourceManager);
Assert.IsTrue(errors.IsEmpty);
Checks:
- That all enum members has keys in the
ResourceManager
- That all keys has non null value for all cultures in
Translator.AllCultures
errors.ToString(" ", Environment.NewLine);
Prints a formatted report with the errors found, sample:
Key: EnglishOnly
Missing for: { de, sv }
Key: Value___0_
Has format errors, the formats are:
Value: {0}
null
Värde: {0} {1}
Validate a formatstring like this:
Validate.Format("Value: {0}", 1);
Debug.Assert(Validate.IsValidFormat("Value: {0}", 1), "Invalid format...");
Conveience API for testing formatstrings.
Returns true if the string contains placeholders like "Value: {0}"
and is a valid format string.
Returns true if the string contains placeholders like "Value: {0}"
that matches the number of parameters and is a valid format string.
A simple control for changing current language. A few flags are included in the library, many are probably missing.
Default is false.
If true it popolates itself with Translator.Cultures
in the running application and picks the default flag or null.
<l:LanguageSelector AutogenerateLanguages="True" />
<l:LanguageSelector>
<l:Language Culture="de-DE"
FlagSource="pack://application:,,,/Gu.Wpf.Localization;component/Flags/de.png" />
<l:Language Culture="en-GB"
FlagSource="pack://application:,,,/Gu.Wpf.Localization;component/Flags/en.png" />
<l:Language Culture="sv-SE"
FlagSource="pack://application:,,,/Gu.Wpf.Localization;component/Flags/sv.png" />
</l:LanguageSelector>