简体   繁体   中英

Xamarin: passing parameters from binding to custom control

I've been learning the Xamarin framework lately, and I wanted to create a reusable control element that displays some properties of an object. To remove redundancy, I wanted to pass the complete object to the control and have it manage how to display it. However, I'm encountering strange behaviour when passing it an object from a binding.

Instead of receiving the object instance, it only receives some instance of Xamarin.Forms.internals<TypedBinding<CoffeeCounter.Demo.Page, CoffeeCounter.Demo.Parameter>. I'd either need to extract the instance of the object from this or change something such that the actual instance is already passed.

Here is a compact demo of the problem. First a simple page view, with an instance of the reusable control.

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:demo="clr-namespace:CoffeeCounter.Demo;assembly=CoffeeCounter"
    x:Class="CoffeeCounter.Demo.Page"
    x:DataType="demo:Page">
    <ContentPage.Content>
        <StackLayout>
            <demo:Control Parameter="{Binding Parameter}"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

It receives the parameter object with the properties to display from the code-behind.

using Xamarin.Forms;

namespace CoffeeCounter.Demo {
    public partial class Page : ContentPage {
        public Page() {
            InitializeComponent();
        }
        
        public Parameter Parameter => new Parameter{Foo="Football", Bar="Barricade"};
    }
}

And the parameter class simply looks like this.

namespace CoffeeCounter.Demo {
    public class Parameter {
        public string Foo {get; set;}
        public string Bar {get; set;}
    
        public override string ToString() {
            return "Foo: " + Foo + ", " + "Bar: " + Bar;
        }
    }
}

The control is then built like this.

<?xml version="1.0" encoding="UTF-8"?>
<ContentView 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="CoffeeCounter.Demo.Control">
    <Label x:Name="Title" Text=""/>
</ContentView>
using Xamarin.Forms;

namespace CoffeeCounter.Demo {
    public partial class Control {
        public static readonly BindableProperty PARAMETER = BindableProperty.Create(
            "Parameter",
            typeof(object),
            typeof(Control),
            null,
            BindingMode.TwoWay,
            propertyChanged: (bindable, oldValue, newValue) => {
                var control = (Control) bindable;
                control.Title.Text = newValue.ToString();
            }
        );

        public object Parameter {
            set => SetValue(PARAMETER, value);
        }
        public Control() {
            InitializeComponent();
        }
    }
}

I'm aware the custom control can probably make use of bindings as well to update its contents, but that's not the point of this question.

Thanks in advance for any answers:)

Your code is correct but there are few errors.

    public Page()
    {
        InitializeComponent();
        BindingContext = this; //add this line
    }

    public Parameter Parameter => new Parameter { Foo = "Football", Bar = "Barricade" };

Your Control.Xaml.cs should be like this.

    public Control()
    {
        InitializeComponent();
    }

    public static readonly BindableProperty ParameterProperty = BindableProperty.Create(
        nameof(Parameter),
        typeof(object),
        typeof(Control),
        null,
        BindingMode.TwoWay,
        propertyChanged: (bindable, oldValue, newValue) => {
            var control = (Control)bindable;
            control.Title.Text = newValue.ToString();
        }
    );

    public object Parameter
    {
        set => SetValue(ParameterProperty, value);
    }

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