【问题标题】:Xamarin Forms Cross Platform App Resource File with StringFormatXamarin 使用 StringFormat 形成跨平台应用程序资源文件
【发布时间】:2019-08-06 23:02:00
【问题描述】:

有没有办法将 StringFormat 应用于资源文件中的值。我基本上想要这样的东西:

Text="{localapp:Translate Port, StringFormat='{0}:'}"

基本上我不想在资源文件中放置标点符号,这样我就可以在我的应用程序的更多地方重复使用该值。任何帮助将不胜感激。

【问题讨论】:

    标签: xamarin.forms string-formatting globalization resource-files


    【解决方案1】:

    首先我们需要在我们的翻译 MarkupExtension 中添加一个进一步的属性来支持 StringFormat:

    [ContentProperty("Text")]
    public class TranslateExtension : IMarkupExtension
    {
        public string Text { get; set; }
    
        public string StringFormat { get; set; }
    
        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (string.IsNullOrEmpty(Text))
                return null;
    
            if (!string.IsNullOrEmpty(StringFormat))
                return string.Format(StringFormat, Resources.ResourceManager.GetString(Text));
    
            return Resources.ResourceManager.GetString(Text);
        }
    }
    

    现在我们可以像这样在 XAML 中使用 StringFormat:

    <Label Text="{utilities:Translate Port, StringFormat='{0}:'}"/>
    

    现在假设我们已经定义了诸如 Port="MyPort" 这样的资源,标签的输出将是:

    MyPort:
    

    【讨论】:

    • 所以我的 TranslateExtension 类中已经有一个 ProvideValue 函数。我不得不合并/移动东西,我让它工作。我对这个答案投了赞成票,但我将提供我在另一个问题的答案中使用的完整的 ProvideValue 函数代码。
    【解决方案2】:

    感谢 VahidShir 提供解决方案的快速启动和基本核心。这是我的 TranslateExtension 类中的 ProvideValue 函数的实际代码,它似乎正在工作。

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Text == null)
                return string.Empty;
    
            var translation = ResMgr.Value.GetString(Text, ci);
            if (translation == null)
            {
    #if DEBUG
                throw new ArgumentException(
                    string.Format("Key '{0}' was not found in resources '{1}' for culture '{2}'.", Text, ResourceId, ci.Name),
                    "Text");
    #else
                translation = Text; // HACK: returns the key, which GETS DISPLAYED TO THE USER
    #endif
            }
    
            if (!string.IsNullOrEmpty(StringFormat))
                translation =  string.Format(StringFormat, translation);
    
            return translation;
        }
    

    我希望这对其他人有所帮助。

    【讨论】:

      【解决方案3】:

      这是使用资源文件中的值的解决方案。

      创建资源文件ConstValue.cs

      public static class ConstValue
      {
         public static string ValueOne { get; set; } = "abc";
      }
      

      并且还需要一个价值模型ValueModel.cs

      public class ValueModel()
      {
      
          public string  Value { get; set;}
      
          public ValueModel()
          {
              Value = ConstValue.ValueOne;
          }
      }
      

      然后在 ContentPage.cs 中,使用这个模型

      BindingContext = new ValueModel();
      

      Xaml中的Last可以如下使用:

      <Label Text="{Binding Value,StringFormat='This is {0}'}" />
      

      注意

      如果直接使用类中的值,它将不起作用。如:

      <Label Text="{Binding Source={x:Static localapp:ConstValue.ValueOne},StringFormat='this is {0}'}"/>
      

      最重要的是它需要绑定模型才能使用类中的值。这也与MVVM架构相匹配。

      或者

      使用 Xaml 资源可以做到这一点:

      <StackLayout.Resources>
          <x:String x:Key="stringkey">123</x:String>
      </StackLayout.Resources>
      
      <Label Text="{Binding Source={StaticResource Key=stringkey},StringFormat='the value is {0}'}" />
      

      【讨论】:

      • 虽然我没有尝试过 - 我相信它会起作用。然而,它似乎比以前的解决方案更复杂。
      • @GeorgeMCeaserJr 感谢您的回复,很高兴您解决了!
      猜你喜欢
      • 2021-02-14
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多