简体   繁体   中英

Xamarin.Forms MarkupExtension for binding

I want to make markup extension to simplify bidning. I have dictionary and I bind that property to a Label in the view. I have ValueConverter that takes this dictinary and I pass ConverterParameter which is a string and it finds

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

but I have to do same thing for different labels but the key (ConverterParameter) will be different, the rest will remain same

I want a markupextension that will allow me to write this:

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

this markup should generate binding to the property named "Tanslations" with valueconverter of TranslationWithKeyConverter and ConverterParameter with value of Key.

I tried to do it but it does not work:

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);
    }
}

nothing is displayed on the label.

Let's start with the obvious warning: you shouldn't write your own MarkupExtensions only because it simplifies the syntax. The XF Xaml parser, and the XamlC Compiler can do some optimization tricks on known MarkupExtensions, but can't on yours.

Now that you're warned, we can move on.

What you do probably works for the normal Xaml parser provided you use the correct names, unlike what you pasted) but certainly does not with XamlC turned on. Instead of implementing IMarkupExtension , you should implement IMarkupExtension<BindingBase> like this:

[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);
    }
}

and then you can use it like in:

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

or

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM