Xamarin.Forms标记扩展用于绑定。

3

我希望制作标记扩展来简化绑定。 我有一个字典,将该属性绑定到视图中的标签上。 我有一个ValueConverter,它使用这个字典,并传递一个字符串作为ConverterParameter,然后找到

<Label Text="{Binding Tanslations,Converter={StaticResource TranslationWithKeyConverter}, ConverterParameter='Test'}"/>

但是我需要为不同的标签做相同的事情,只是键(转换器参数)不同,其他内容都相同

我想要一个标记扩展,使我能够这样写:

<Label Text="{local:MyMarkup Key=Test}"/>

这个标记应该生成到名为“Translations”的属性绑定,使用TranslationWithKeyConverter的值转换器和ConverterParameter参数,并且其值为Key。

我试过了,但它没有起作用:

public class WordByKey : IMarkupExtension
{
    public string Key { get; set; }
    public object ProvideValue(IServiceProvider serviceProvider)
    {
        return new Binding("Tanslations", BindingMode.OneWay, converter: new TranslationWithKeyConverter(), converterParameter: Key);
    }
}

1
文本是一个字符串,因此标记扩展需要从ProvideValue提供一个字符串,就像Binding标记扩展一样。让一个标记扩展返回另一个标记扩展是行不通的。 - JimBobBennett
1
Xamarin.Forms已经有了推荐的做法。请参见https://developer.xamarin.com/guides/xamarin-forms/advanced/localization/。 - matthewrdev
1个回答

9
让我们先说一个明显的警告:你不应该只为了简化语法而编写自己的MarkupExtensions。XF Xaml解析器和XamlC编译器可以对已知的MarkupExtensions进行一些优化技巧,但无法对你的MarkupExtension进行优化。
现在你已经被警告了,我们可以继续了。
如果你使用正确的名称(不像你粘贴的那样),你所做的可能适用于普通的Xaml解析器,但是在启用XamlC的情况下肯定不适用。你应该实现IMarkupExtension而不是IMarkupExtension,就像这样:
[ContentProperty("Key")]
public sealed class WordByKeyExtension : IMarkupExtension<BindingBase>
{
    public string Key { get; set; }
    static IValueConverter converter = new TranslationWithKeyConverter();

    BindingBase IMarkupExtension<BindingBase>.ProvideValue(IServiceProvider serviceProvider)
    {
        return new Binding("Tanslations", BindingMode.OneWay, converter: converter, converterParameter: Key);
    }

    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
    {
        return (this as IMarkupExtension<BindingBase>).ProvideValue(serviceProvider);
    }
}

然后您可以像这样使用它:
<Label Text="{local:WordByKey Key=Test}"/>

或者

<Label Text="{local:WordByKey Test}"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接