将 IMarkupExtension 与 StringFormat 一起使用
Use IMarkupExtension together with StringFormat
我正在使用 Xamarin 的 TranslateExtension
。是否可以在呼叫中添加 StringFormat
?
目前,我有
<Label Text="{i18n:Translate User}" />
但我需要这样的东西
<Label Text="{i18n:Translate User, StringFormat='{0}:'}" />
如果我做后者,我得到
Xamarin.Forms.Xaml.XamlParseException: Cannot assign property "StringFormat": Property does not exists, or is not assignable, or mismatching type between value and property
我知道我可以添加另一个带冒号的翻译,但最好有不同的选择。
您可以向 TranslateExtension 添加参数 属性。
我的 TranslateExtension 看起来像这样。您可以获取参数部分并将其添加到 Xamarin 示例中的部分。
[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension
{
public string Text { get; set; }
public string Parameter { get; set; }
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
try
{
if (Text == null)
return null;
var culture = new CultureInfo(CultureHelper.CurrentIsoLanguage);
var result = LocalizationResources.ResourceManager.GetString(Text, culture);
if (string.IsNullOrWhiteSpace(Parameter))
{
return string.IsNullOrWhiteSpace(result) ? "__TRANSLATE__" : result;
}
return string.IsNullOrWhiteSpace(result) ? "__TRANSLATE__" : string.Format(result, Parameter);
}
catch (Exception ex)
{
TinyInsights.TrackErrorAsync(ex);
return "__TRANSLATE__";
}
}
}
我在这里更新了 Xamarin 示例:
[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension
{
readonly CultureInfo ci = null;
const string ResourceId = "UsingResxLocalization.Resx.AppResources";
static readonly Lazy<ResourceManager> ResMgr = new Lazy<ResourceManager>(() => new ResourceManager(ResourceId, IntrospectionExtensions.GetTypeInfo(typeof(TranslateExtension)).Assembly));
public string Text { get; set; }
public string StringFormat {get;set;}
public TranslateExtension()
{
if (Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.Android)
{
ci = DependencyService.Get<ILocalize>().GetCurrentCultureInfo();
}
}
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.IsNullOrWhitespace(StringFormat)
return string.Format(StringFormat, translation);
return translation;
}
}
晚会有点晚了,但是用标准的扩展名和 XAML 来做,像这样:
<Label Text="{Binding YourDynamicValue, StringFormat={i18n:Translate KeyInResources}}"/>
您的翻译应该类似于:Static text {0}
。其中 {0}
替换为您绑定的值。
问题是 Translate
扩展只是从资源中获取你的字符串,并没有 StringFormat
属性 等。但是你可以分配检索到的资源Binding
的 StringFormat
的值。
我正在使用 Xamarin 的 TranslateExtension
。是否可以在呼叫中添加 StringFormat
?
目前,我有
<Label Text="{i18n:Translate User}" />
但我需要这样的东西
<Label Text="{i18n:Translate User, StringFormat='{0}:'}" />
如果我做后者,我得到
Xamarin.Forms.Xaml.XamlParseException: Cannot assign property "StringFormat": Property does not exists, or is not assignable, or mismatching type between value and property
我知道我可以添加另一个带冒号的翻译,但最好有不同的选择。
您可以向 TranslateExtension 添加参数 属性。
我的 TranslateExtension 看起来像这样。您可以获取参数部分并将其添加到 Xamarin 示例中的部分。
[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension
{
public string Text { get; set; }
public string Parameter { get; set; }
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
try
{
if (Text == null)
return null;
var culture = new CultureInfo(CultureHelper.CurrentIsoLanguage);
var result = LocalizationResources.ResourceManager.GetString(Text, culture);
if (string.IsNullOrWhiteSpace(Parameter))
{
return string.IsNullOrWhiteSpace(result) ? "__TRANSLATE__" : result;
}
return string.IsNullOrWhiteSpace(result) ? "__TRANSLATE__" : string.Format(result, Parameter);
}
catch (Exception ex)
{
TinyInsights.TrackErrorAsync(ex);
return "__TRANSLATE__";
}
}
}
我在这里更新了 Xamarin 示例:
[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension
{
readonly CultureInfo ci = null;
const string ResourceId = "UsingResxLocalization.Resx.AppResources";
static readonly Lazy<ResourceManager> ResMgr = new Lazy<ResourceManager>(() => new ResourceManager(ResourceId, IntrospectionExtensions.GetTypeInfo(typeof(TranslateExtension)).Assembly));
public string Text { get; set; }
public string StringFormat {get;set;}
public TranslateExtension()
{
if (Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.Android)
{
ci = DependencyService.Get<ILocalize>().GetCurrentCultureInfo();
}
}
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.IsNullOrWhitespace(StringFormat)
return string.Format(StringFormat, translation);
return translation;
}
}
晚会有点晚了,但是用标准的扩展名和 XAML 来做,像这样:
<Label Text="{Binding YourDynamicValue, StringFormat={i18n:Translate KeyInResources}}"/>
您的翻译应该类似于:Static text {0}
。其中 {0}
替换为您绑定的值。
问题是 Translate
扩展只是从资源中获取你的字符串,并没有 StringFormat
属性 等。但是你可以分配检索到的资源Binding
的 StringFormat
的值。