【问题标题】:WPF StringFormat and Localization in XAMLXAML 中的 WPF StringFormat 和本地化
【发布时间】:2013-01-24 12:23:11
【问题描述】:

操作系统:WP8

我正在尝试格式化一个字符串,该字符串是转换器进行绑定的结果。除了字符串格式数据的本地化之外,所有这些都有效,我不知道如何合并。微软的文档对此并不十分清楚,我想知道是否有人能指出我正确的方向。

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

这看起来并不是一件完全不可能的事情。

谢谢!

-绳子

【问题讨论】:

    标签: c# .net wpf localization string-formatting


    【解决方案1】:

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

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

    一般来说,一旦你有了这个,你就可以在你的 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}}"/>
    

    【讨论】:

    • 谢谢。一般来说,我对如何本地化应用程序有很好的了解。事实上,除了 StringFormat 字符串之外,所有这些都已完成。正如您在最初的示例中所见,我有一个对象(在本例中为日期)通过转换器发送,该对象根据转换器的参数将其更改为字符串。这一切都完美无缺。但是,如果将 StringFormat 参数添加到绑定中,则无法获取初始转换的输出并本地化 StringFormat 部分,在本例中为“Received On:”字符串。
    • @CordAwtry - 在这种情况下,将格式化字符串放入您的转换器中。
    【解决方案2】:

    在不使用其他转换器或修改底层模型的情况下处理此问题的一种方法是将字符串拆分为两个单独的 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>
    

    这样你就可以对字符串“Received On:”使用正常的本地化

    【讨论】:

      【解决方案3】:

      概括@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。

      注意:转换器在每个 PropertyChanged 上执行,因此可能会或可能不会比使用带有 DataBinding 的 StringFormat 慢。

      【讨论】:

        猜你喜欢
        • 2010-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-22
        • 2011-04-30
        • 2011-06-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多