直接在XAML中使用.resw文件中的字符串

时间:2016-11-23 14:29:45

标签: c# xaml localization uwp-xaml

我知道从.resw文件引用本地化字符串的常用方法是这样的:

XAML:

<Button x:Uid="ButtonUid" />

Resources.resw:

ButtonUid.Content = "Hello World"

但也有可能这样做:

XAML(伪代码):

<Button Content = "$buttonLabel" />

Resources.resw:

buttonLabel = "Hello World"

我想在第二个例子中做到这一点的原因是因为这是一个我从iOS和Android移植到WP的应用程序。我想将iOS或Android字符串文件转换为.resw语法,但不会遍历每个字符串并添加.Content或.Text或其他用途。有一个简单的解决方案吗?

2 个答案:

答案 0 :(得分:2)

我曾经做过类似的事情,我们在Android字符串资源文件中添加了任何新字符串,然后使用自定义构建工具将这些字符串转换为iOS和Windows格式。

Android字符串可能如下所示:

<string name="Hello">Hello, World!</string>

我们的工具将其转换为Windows字符串资源:

<data name="Hello">
  <value>Hello, World!</value>
</data>

接下来,添加一个对提供的没有任何作用的转换器,而是假设其参数是资源ID:

public sealed class LocalizeConverter : IValueConverter
{
    private static readonly ResourceLoader Loader = ResourceLoader.GetForViewIndependentUse("/Resources");

    public object Convert(object value, Type targetType, object parameter, string language)
    {
        string resourceId = parameter as string;
        return !string.IsNullOrEmpty(resourceId) ? Loader.GetString(resourceId) : DependencyProperty.UnsetValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotSupportedException();
    }
}

现在让您的XAML可以使用该转换器,可能是这样的:

<Page.Resources>
    <local:LocalizeConverter x:Key="LocalizeConverter" />
</Page.Resources>

最后,按照以下方式设置Button Content属性:

<Button
    Content="{x:Bind Converter={StaticResource LocalizeConverter}, ConverterParameter=Hello, Mode=OneTime}"
/>

请注意,我们不向转换器提供任何值。 (在WPF中我会创建一个标记扩展。遗憾的是,这个选项在UWP中不可用,所以我想出了这个无值转换器选项作为替代选择。)

如果你想变得更加笨拙,请考虑一下:

<Button
    Content="{x:Bind Language, Converter={StaticResource LocalizeConverter}, ConverterParameter=Hello, Mode=OneWay}"
/>

如果您将资源本地化为其他语言,则可以动态更改语言。 (注意Mode=OneWay而不是Mode=OneTime。)

答案 1 :(得分:2)

您可以使用var a = [1,2,3]; var b = [0,1,4,3,9,10,2,5,6]; // 1,2,3 in wrong order var c = [0,4,1,5,6,2,8,3,5]; // 1,2,3 in right order // using foreach function compare(a,b){ var i = 0; b.forEach(function(el){ if(el == a[i]) i++; }) return i == a.length; } // using reduce function compare2(a,b){ return b.reduce(function(i, el){ return el == a[i] ? i + 1 : i; }, 0) == a.length; } console.log(compare(a,b) == false); // should be false console.log(compare(a,c) == true); // should be true console.log(compare2(a,b) == false); // should be false console.log(compare2(a,c) == true); // should be true

CustomXamlResourceLoader

然后在App.xaml.cs构造函数中:
public class XamlResourceLoader : CustomXamlResourceLoader { private readonly ResourceLoader _loader; public XamlResourceLoader() { _loader = ResourceLoader.GetForViewIndependentUse(); } protected override object GetResource(string resourceId, string objectType, string propertyName, string propertyType) { return _loader.GetString(resourceId) ?? resourceId; } }

最后在你的xaml中:
CustomXamlResourceLoader.Current = new XamlResourceLoader();