Xamarin 使用 StringFormat 形成跨平台应用程序资源文件
Xamarin Forms Cross Platform App Resource File with StringFormat
有没有办法将 StringFormat 应用于资源文件中的值。我基本上想要这样的东西:
Text="{localapp:Translate Port, StringFormat='{0}:'}"
基本上我不想在资源文件中放置标点符号,这样我就可以在我的应用程序的更多地方重用该值。任何帮助将不胜感激。
首先,我们需要在我们的翻译 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:
这是一个使用资源文件中的值的解决方案。
正在创建资源文件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中可以使用如下:
<Label Text="{Binding Value,StringFormat='This is {0}'}" />
注:
如果直接使用 class 中的值,它将不起作用。如:
<Label Text="{Binding Source={x:Static localapp:ConstValue.ValueOne},StringFormat='this is {0}'}"/>
最重要的是它需要绑定模型才能使用来自class.This的值,这也与 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}'}" />
感谢 VahidShir 快速启动和解决方案的基本核心。这是我的 TranslateExtension class 中的 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;
}
我希望这对其他人有所帮助。
有没有办法将 StringFormat 应用于资源文件中的值。我基本上想要这样的东西:
Text="{localapp:Translate Port, StringFormat='{0}:'}"
基本上我不想在资源文件中放置标点符号,这样我就可以在我的应用程序的更多地方重用该值。任何帮助将不胜感激。
首先,我们需要在我们的翻译 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:
这是一个使用资源文件中的值的解决方案。
正在创建资源文件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中可以使用如下:
<Label Text="{Binding Value,StringFormat='This is {0}'}" />
注:
如果直接使用 class 中的值,它将不起作用。如:
<Label Text="{Binding Source={x:Static localapp:ConstValue.ValueOne},StringFormat='this is {0}'}"/>
最重要的是它需要绑定模型才能使用来自class.This的值,这也与 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}'}" />
感谢 VahidShir 快速启动和解决方案的基本核心。这是我的 TranslateExtension class 中的 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;
}
我希望这对其他人有所帮助。