WPF 字符串格式和 XAML 中的本地化

本文关键字:本地化 XAML 字符串 格式 WPF | 更新日期: 2023-09-27 17:55:51

OS: WP8

我正在尝试格式化一个字符串,这是转换器采用绑定的结果。除了字符串格式数据的本地化之外,所有这些都有效,我对如何合并一无所知。Microsoft的文档对此并不那么清楚,我想知道是否有人可以指出我正确的方向。

<TextBlock Text="{Binding Date, StringFormat='Received On: {0}', ConverterParameter=shortdatewithyear, Converter={StaticResource DateTimeToTimeConvert}}"/>

它看起来不像是一件完全离谱的事情。

谢谢!

-绳子

WPF 字符串格式和 XAML 中的本地化

在您的特定情况下,我会从转换器的资源文件中提取字符串,然后 .Net 提供的本地化就可以工作了。在构建字符串时,这可能更为重要,并且构建字符串的顺序可能会在不同的语言中更改。

您以标准方式创建资源文件 - "MyResource.resx"来存储默认语言的字符串,然后您可以创建一个名为"MyResource.Fr-fr.resx"的本地化版本(如果您使用的是法语)。这将在第一个实例中自动加载并搜索字符串。如果找不到,代码将从默认资源文件中提取字符串。这样,您就不必翻译所有内容 - 对于US/GB拼写差异很有用。

通常,一旦你有了这个,你就可以在你的 XAML 中拥有本地化的字符串

添加本地化类:

public class Localize : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyChange(String name)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
    #endregion
    #region 'Public Properties'
    //Declarations
    private static Resources.MyResources _myResources = new Resources.MyResources();
    public Resources.MyResources myResources
    {
        get { return _myResources; }
        set { NotifyChange("MyResources"); }
    }
    #endregion
}

然后在 XAML 中,将此添加到用户控件的资源中:

<local:Localize x:Key="myResource"
                xmlns:local="clr-namespace:MyProject" />

然后你可以使用它:

<TextBlock Text="{Binding myResource.MyString, Source={StaticResource myResource}}"/>

在不使用其他转换器或修改基础模型的情况下处理此问题的一种方法是将字符串拆分为两个单独的 UI 元素。例如StackPanel内的两个TextBlock,如下所示:

<StackPanel Orientation="Horizontal">
    <TextBlock Text="{x:Static properties:Resources.ReceivedOn}" Margin="0,0,5,0"/>
    <TextBlock Text="{Binding Date, ConverterParameter=shortdatewithyear, Converter={StaticResource DateTimeToTimeConvert}}"/>
</StackPanel>

这样,您就可以对字符串"接收日期:"使用正常的本地化

概括

一下@Jakob Möllås的答案:

问题所在

<TextBlock Text="{Binding Date, StringFormat='Received On: {0}', ConverterParameter=shortdatewithyear, Converter={StaticResource DateTimeToTimeConvert}}"/>

是绑定以某种方式缓存了 StringFormat 的值,即使您在 DataGrid 中有一个 GroupStyle 并重新加载 DataGrid 的内容,它也不会更新。使用后无法更改绑定(您会收到例外)。所以解决方案是使用这样的转换器:

public class StringFormatConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var formatString = parameter as string;
        if(string.IsNullOrEmpty(formatString))
             return null;
        return string.Format(formatString, value);
    }
    // ...
}

然后在 XAML 中:

<!-- ... declare your converter at some place ... -->
<!-- then -->
<TextBlock Text="{Binding Date, Converter={StaticResource LocalizationConverter}, ConverterParameter={x:Static names:MyClass.LocalizedStringFormat}}"/>

因此,当您更新 MyClass.LocalizedStringFormat 的值(也许您更改了程序中的显示语言)时,您需要做的就是为使用本地化 StringFormat 的属性抛出 PropertyChanged。

注意:转换器在每个 PropertyChange 上执行,因此可能会或可能不会比将 StringFormat 与 DataBinding 一起使用慢一些。