WPF本地化:带StringFormat的DynamicResource?

我正在使用ResourceDictionary在.NET 4中进行本地化。 有没有人有一个使用字符串格式的值的解决方案?

例如,假设我有一个键为“SomeKey”的值:

 You ran {0} miles  

在TextBlock中使用它:

  

例如,如何将具有SomeKey值的整数组合为格式字符串?

您需要以某种方式绑定到ViewModel.Value,然后使用(嵌套)绑定到格式字符串。

当您只有一个值时:

  

当你还有{1}等时,你需要MultiBinding。

编辑:

如果您真的想要在实时表单中更改语言,那么明智的方法可能是在ViewModel中进行所有格式化。 无论如何,我很少在MVVM中使用StringFormat或MultiBinding。

如果您尝试将Miles属性绑定并格式化为“TextBlock”,则可以执行以下操作:

所以,我最终提出了一个解决方案,允许我在ResourceDictionary中使用格式字符串,并能够在运行时动态更改语言。 我认为它可以改进,但它的工作原理。

此类将资源键转换为ResourceDictionary中的值:

 public class Localization { public static object GetResource(DependencyObject obj) { return (object)obj.GetValue(ResourceProperty); } public static void SetResource(DependencyObject obj, object value) { obj.SetValue(ResourceProperty, value); } // Using a DependencyProperty as the backing store for Resource. This enables animation, styling, binding, etc... public static readonly DependencyProperty ResourceProperty = DependencyProperty.RegisterAttached("Resource", typeof(object), typeof(Localization), new PropertyMetadata(null, OnResourceChanged)); private static void OnResourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { //check if ResourceReferenceExpression is already registered if (d.ReadLocalValue(ResourceProperty).GetType().Name == "ResourceReferenceExpression") return; var fe = d as FrameworkElement; if (fe == null) return; //register ResourceReferenceExpression - what DynamicResourceExtension outputs in ProvideValue fe.SetResourceReference(ResourceProperty, e.NewValue); } } 

此类允许将ResourceDictionary中的值用作String.Format()中的format参数

 public class FormatStringConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (values[0] == DependencyProperty.UnsetValue || values[0] == null) return String.Empty; var format = (string)values[0]; var args = values.Where((o, i) => { return i != 0; }).ToArray(); return String.Format(format, args); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } 

示例用法1 :在此示例中,我使用MultiBinding中的FormatStringConverter将其Binding集合转换为所需的输出。 例如,如果“SomeKey”的值为“对象id为{0}”并且“Id”的值为“1”,则输出将变为“对象id为1”。

          

示例用法2 :在此示例中,我使用与Converter的绑定将资源键更改为更详细的内容以防止键冲突。 例如,如果我有枚举值Enum.Value(默认显示为“Value”),我使用转换器附加其命名空间以创建更独特的键。 因此该值变为“My.Enums.Namespace.Enum.Value”。 然后,Text属性将解析为“My.Enums.Namespace.Enum.Value”的值在ResourceDictionary中。

         

示例用法3 :在此示例中,键是文字,仅用于在ResourceDictionary中查找其对应的值。 例如,如果“SomeKey”具有值“SomeValue”,那么它将只输出“SomeValue”。