Last active
September 24, 2017 07:31
-
-
Save canton7/e4d250ec9fa625913efe to your computer and use it in GitHub Desktop.
WPF Localization toolkit, see http://antonymale.co.uk/internationalization-in-wpf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Globalization; | |
using System.Linq; | |
using System.Windows.Data; | |
namespace LocalizationDemo.Localization | |
{ | |
/// <summary> | |
/// Localization converter which takes a static key and is applied to a single value | |
/// </summary> | |
public class StaticKeySingleValueConverter : IValueConverter | |
{ | |
/// <summary> | |
/// Gets or sets the key to use to look up a localized string | |
/// </summary> | |
public string Key { get; set; } | |
/// <summary> | |
/// Gets or sets an optional converter to apply to the value | |
/// </summary> | |
public IValueConverter Converter { get; set; } | |
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |
{ | |
if (this.Key == null) | |
throw new InvalidOperationException("Key must not be null"); | |
var convertedValue = (this.Converter == null) ? value : this.Converter.Convert(value, targetType, parameter, culture); | |
return Localizer.Translate(this.Key, convertedValue); | |
} | |
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |
{ | |
throw new NotSupportedException(); | |
} | |
} | |
/// <summary> | |
/// Localization converter which takes a static key and is applied to multiple values | |
/// </summary> | |
public class StaticKeyMultipleValuesConverter : IMultiValueConverter | |
{ | |
/// <summary> | |
/// Gets or sets the key to use to look up a localized string | |
/// </summary> | |
public string Key { get; set; } | |
/// <summary> | |
/// Gets or sets an optional converter to apply to the values. May return a scalar or an array | |
/// </summary> | |
public IMultiValueConverter Converter { get; set; } | |
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) | |
{ | |
if (this.Key == null) | |
throw new InvalidOperationException("Key must not be null"); | |
if (this.Converter == null) | |
return Localizer.Translate(this.Key, values); | |
var convertedValues = this.Converter.Convert(values, targetType, parameter, culture); | |
return Localizer.Translate(this.Key, convertedValues as object[] ?? new object[] { convertedValues }); | |
} | |
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) | |
{ | |
throw new NotSupportedException(); | |
} | |
} | |
/// <summary> | |
/// Localization converter which is applied to a key binding | |
/// </summary> | |
public class BoundKeyNoValuesConverter : IValueConverter | |
{ | |
/// <summary> | |
/// Gets or sets an optional converter to apply to the key binding first | |
/// </summary> | |
public IValueConverter Converter { get; set; } | |
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |
{ | |
var stringValue = (this.Converter == null) ? value as string : this.Converter.Convert(value, targetType, parameter, culture) as string; | |
return (stringValue != null) ? Localizer.Translate(stringValue) : null; | |
} | |
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |
{ | |
throw new NotSupportedException(); | |
} | |
} | |
/// <summary> | |
/// Localization converter which is applied to a MultiBinding of { Key Binding, Value Binding, [Value Binding [...]] } | |
/// </summary> | |
public class BoundKeyWithValuesConverter : IMultiValueConverter | |
{ | |
/// <summary> | |
/// Gets or sets an optional converter to apply to the value bindings (not the key binding) | |
/// </summary> | |
public IMultiValueConverter ValuesConverter { get; set; } | |
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) | |
{ | |
// The first item is the key. The rest are the values | |
if (values.Length < 1) | |
return null; | |
var key = values[0] as string; | |
if (key == null) | |
return null; | |
var parameters = values.Skip(1).ToArray(); | |
if (this.ValuesConverter == null) | |
return Localizer.Translate(key, parameters); | |
var convertedParameters = this.ValuesConverter.Convert(parameters, targetType, parameter, culture); | |
return Localizer.Translate(key, convertedParameters as object[] ?? new object[] { convertedParameters }); | |
} | |
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) | |
{ | |
throw new NotSupportedException(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using LocalizationDemo.Properties; | |
using System; | |
using System.Threading; | |
namespace LocalizationDemo.Localization | |
{ | |
public static class Localizer | |
{ | |
public static string Translate(string key, params object[] parameters) | |
{ | |
var culture = Thread.CurrentThread.CurrentUICulture; | |
var format = Resources.ResourceManager.GetString(key, culture); | |
if (format == null) | |
return "!" + key + (parameters.Length > 0 ? ":" + String.Join(",", parameters) : "") + "!"; | |
return String.Format(culture, format, parameters); | |
} | |
public static string Format(string format, params object[] parameters) | |
{ | |
return String.Format(Thread.CurrentThread.CurrentCulture, format, parameters); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Windows.Data; | |
using System.Windows.Markup; | |
namespace LocalizationDemo.Localization | |
{ | |
public class LocExtension : MarkupExtension | |
{ | |
/// <summary> | |
/// Gets or sets the key to use to look up the appropriate value to display. | |
/// </summary> | |
/// <remarks> | |
/// Either this or <see cref="KeyBinding"/> must be set. | |
/// </remarks> | |
public string Key { get; set; } | |
/// <summary> | |
/// Gets or sets the key binding to use the look up the appropriate value to display. | |
/// </summary> | |
/// <remarks> | |
/// The binding is evaluated, and the result used as the key. | |
/// Either this or <see cref="Key"/> must be set. | |
/// </remarks> | |
public Binding KeyBinding { get; set; } | |
/// <summary> | |
/// Gets or sets an optional binding to use to supply a single parameter to substitute into the value to display. | |
/// </summary> | |
/// <remarks> | |
/// This or <see cref="ParamBindings"/> may be set, but not both. | |
/// </remarks> | |
public Binding ParamBinding { get; set; } | |
/// <summary> | |
/// Gets or set an optional MultiBinding to use to supply multiple parameters to substitute into the value to display. | |
/// </summary> | |
/// <remarks> | |
/// This or <see cref="ParamBinding"/> may be set, but not both. | |
/// </remarks> | |
public MultiBinding ParamBindings { get; set; } | |
public LocExtension() | |
{ | |
} | |
public LocExtension(string key) | |
{ | |
this.Key = key; | |
} | |
public override object ProvideValue(IServiceProvider serviceProvider) | |
{ | |
if (this.Key == null && this.KeyBinding == null) | |
throw new ArgumentException("Either Key or KeyBinding must be set"); | |
if (this.Key != null && this.KeyBinding != null) | |
throw new ArgumentException("Either Key or KeyBinding must be set, but not both"); | |
if (this.ParamBinding != null && this.ParamBindings != null) | |
throw new ArgumentException("ParamBinding and ParamBindings may not be set at the same time"); | |
// Most of these conditions are redundent, according to the assertions above. However I'll still state them, | |
// for clarity. | |
// A static key, and no values | |
if (this.Key != null && this.KeyBinding == null && this.ParamBinding == null && this.ParamBindings == null) | |
{ | |
// Just returning a string! | |
return Localizer.Translate(this.Key); | |
} | |
// A static key, and a single value | |
if (this.Key != null && this.KeyBinding == null && this.ParamBinding != null && this.ParamBindings == null) | |
{ | |
var converter = new StaticKeySingleValueConverter() { Key = this.Key, Converter = this.ParamBinding.Converter }; | |
this.ParamBinding.Converter = converter; | |
return this.ParamBinding.ProvideValue(serviceProvider); | |
} | |
// A static key, and multiple values | |
if (this.Key != null && this.KeyBinding == null && this.ParamBinding == null && this.ParamBindings != null) | |
{ | |
var converter = new StaticKeyMultipleValuesConverter() { Key = this.Key, Converter = this.ParamBindings.Converter }; | |
this.ParamBindings.Converter = converter; | |
return this.ParamBindings.ProvideValue(serviceProvider); | |
} | |
// A bound key, no values | |
if (this.Key == null && this.KeyBinding != null && this.ParamBinding == null && this.ParamBindings == null) | |
{ | |
var converter = new BoundKeyNoValuesConverter() { Converter = this.KeyBinding.Converter }; | |
this.KeyBinding.Converter = converter; | |
return this.KeyBinding.ProvideValue(serviceProvider); | |
} | |
// A bound key, and one value | |
if (this.Key == null && this.KeyBinding != null && this.ParamBinding != null && this.ParamBindings == null) | |
{ | |
var converter = new BoundKeyWithValuesConverter(); | |
var multiBinding = new MultiBinding() { Converter = converter }; | |
multiBinding.Bindings.Add(this.KeyBinding); | |
multiBinding.Bindings.Add(this.ParamBinding); | |
return multiBinding.ProvideValue(serviceProvider); | |
} | |
// A bound key, and multiple values | |
if (this.Key == null && this.KeyBinding != null && this.ParamBinding == null && this.ParamBindings != null) | |
{ | |
var converter = new BoundKeyWithValuesConverter() { ValuesConverter = this.ParamBindings.Converter }; | |
this.ParamBindings.Bindings.Insert(0, this.KeyBinding); | |
this.ParamBindings.Converter = converter; | |
return this.ParamBindings.ProvideValue(serviceProvider); | |
} | |
throw new Exception("Should never get here"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment