如何在xamarin.forms中的xaml中大写/小写resx绑定?

时间:2017-03-13 11:44:19

标签: xamarin xamarin.forms resx

关注enter image description here和示例xamarin localization topic,我的应用程序多语言化。我的问题有时候,我需要使用有时单词大写,我不想在resx文件中创建另一个翻译作为同一个单词的大写版本。实现这一目标的最佳方法是什么?如果可能延长这个translateextension?或者我应该使用IValueConvertor?如果是,如何在xaml中绑定它

    // You exclude the 'Extension' suffix when using in Xaml markup
        [ContentProperty("Text")]
        public class TranslateExtension : IMarkupExtension
        {
            readonly CultureInfo ci;
            const string ResourceId = "myApp.Resx.AppRes";

            public TranslateExtension()
            {
                if (Device.OS == TargetPlatform.iOS || Device.OS == TargetPlatform.Android)
                {
                    ci = DependencyService.Get<ILocalize>().GetCurrentCultureInfo();
                }
            }

            public string Text { get; set; }

            public object ProvideValue(IServiceProvider serviceProvider)
            {
                if (Text == null)
                    return "";

                ResourceManager resmgr = new ResourceManager(ResourceId
                                    , typeof(TranslateExtension).GetTypeInfo().Assembly);

                var translation = resmgr.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
                }
                return translation;
            }
        }

我的Xaml:

     <Button  Image="ic_add.png"   Text="{resx:Translate AddNew}"
 Command="{Binding AddNew}"   HorizontalOptions="FillAndExpand"/>

我尝试过这样做,但我猜Binding需要在BindingContext中定义一个属性。因此它不起作用,但我如何为resx文件中定义的文本实现它。

Text="{Binding {resx:Translate AddNew}, Converter={StaticResource UpperCaseConverter}}"

3 个答案:

答案 0 :(得分:5)

您可以尝试这样的事情:

<Button Text="{Binding Converter={StaticResource UpperCaseConverter}, ConverterParameter={resx:Translate AddNew}}"/>

这样你就可以访问转换器中的翻译字符串

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
     return parameter.ToString().ToUpper();
}

如果ConverterParameter不起作用,您只需使用密钥并将转换后的资源放入转换器中。

答案 1 :(得分:0)

来自汉德赛德的回答也是正确的,但我在这里找到了更好的解决方案。显然,IMarkupExtension继承类中定义的任何公共属性都可以绑定。参考xamarin doc

中的示例

所以我只是用

扩展了我的TranslationExtension类
public bool IsUpper { get; set; } = false;

并且说明了我需要大写的地方。我希望这可以帮助任何正在寻找相同解决方案的人。

  <Button  Image="ic_add.png"   Text="{resx:Translate AddNew}"
 Command="{Binding AddNew, IsUpper=true}"   HorizontalOptions="FillAndExpand"/>

答案 2 :(得分:-1)

要使其更加可定制,可以在TranslationExtension中添加属性StringCase,如下所示:

[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension
{
    public string Text { get; set; }
    public string StringCase { get; set; }

    ........
    ........

        if (!string.IsNullOrEmpty(StringCase))
        {
            if (StringCase.ToUpper().Equals("UPPER"))
            {
                translation = translation.ToUpper();
            }
            else if (StringCase.ToUpper().Equals("LOWER"))
            {
                translation = translation.ToLower();
            }
        }
        return translation;
    }
}

要保持文本正常:

<Label Text="{resx:Translate AddNew}"/>
<Button Text="{resx:Translate AddNew}"/>

使其成为大写字母:

<Label Text="{resx:Translate AddNew, StringCase=Upper}"/>
<Button Text="{resx:Translate AddNew, StringCase=Upper}"/>

使其变为小写:

<Label Text="{resx:Translate AddNew, StringCase=Lower}"/>
<Button Text="{resx:Translate AddNew, StringCase=Lower}"/>

这样,如果要将其转换为CamelCase,PascalCase,SnakeCase或KebabCase,也可以添加条件(但是,除了大写或小写之外,在您需要转换的情况下可能不会遇到这种情况。)