BinaryTie
BinaryTie

Reputation: 301

Xamarin.Forms Data Binding to class properties

I know that there are a way to bind data of page StackLayout variables to class properties, but unfortunately I don't find any resources about it. I know how to implement simple binding. For example: between Editor and Label . But how can I bind Editor input text to class property ex.: string Number {get; set;} . Here is my class:

public class ThingsObject
    {
        public int Id { get; set; }
        public bool IsStarted { get; set; }
        public string Number {get; set; }
        public string City { get; set; }
        public Zones Zone { get; set; }
        public ContentPage Page;
        public DateTime StartDate { get; set; }
    }

And here is my PageLayout class with StackLayout implementation , variables and binding between them.

public partial class ThingPageLayout : CarouselPage
{
List<ThingsObject> things= new List<ThingsObject>();
public ThingPageLayout()
        {
         things.Add(new ThingsObject() { Id = 1, Number = null, City = null, Zone = null });
         foreach (ThingsObject p in things)
            {
                Children.Add(CreatePage(p));
            }
        }
public ContentPage CreatePage(ThingsObject thing)
        {
            int uniqueId = this.IdPark;
            var page = new ContentPage()
            {
                Content = new StackLayout { }
            };

            var label1 = new Label
            { 
                Text = "Text",
                TextColor = Color.Black,
                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
                HorizontalOptions = LayoutOptions.Center
            };
            ((StackLayout)page.Content).Children.Add(label1);

            var inputText = new Editor
            {
                TextColor = Color.Blue,
                HorizontalOptions = LayoutOptions.Fill,
                VerticalOptions = LayoutOptions.Fill
            };
            ((StackLayout)page.Content).Children.Add(inputText);
            // Binding here //
            label1.BindingContext = inputText;
            label1.SetBinding(Label.TextProperty, "Text");
            // End of binding //
            var activeButton = new Button
            {
                ClassId = uniqueId.ToString(),
                Text = "Button",
                HorizontalOptions = LayoutOptions.Fill,
                VerticalOptions = LayoutOptions.Fill
            };
            ((StackLayout)page.Content).Children.Add(activeButton);
            thing.Page = page;
            return page;
        }
}

And here I would like to bind to my existing object things Number to Editor inserted value. Because when projects starts , Number value is null, but after Editor input I want to bind inserted text to my class property Number.

Upvotes: 1

Views: 3371

Answers (2)

Keith Rome
Keith Rome

Reputation: 3238

The second parameter of the SetBinding() method is a string that designates the target property of your binding context that you wish to bind to a property of the control. The first parameter designates the property of the control that should be updated.

So I am pretty sure that in this line of code:

label1.SetBinding(Label.TextProperty, "Text");

You really intended to specific something other than "Text" for the second parameter, as I don't see a property named Text declared on your ThingsObject class.

The Editor control also has a Text property that you can bind. The code looks very similar, in this example which would establish a binding to your Number property:

inputText.SetBinding(Editor.TextProperty, "Number");

You would also need to set the BindingContext of the editor, but there is a trick you can use to save some code. If a control has bindings but does not have a BindingContext explicitly set, it will look to its parent control (or its parent, and so on) until it finds a BindingContext value. So by changing this line of code in your example:

label1.BindingContext = inputText;

To this:

page.BindingContext = inputText;

Then you don't need to explicitly set the BindingContext of any of the child controls, because they will inherit it from the parent page container.

Upvotes: 1

George Papadakis
George Papadakis

Reputation: 1378

Basically every page (ContentPage, TabPage etc) has a property BindingContext where you assign the object or better a ViewModel that you want to bind to.

So

public class Page1 : ContentPage
    {
        public Page1()
        {
            BindingContext = new ThingsObject();
            var lbl = new Label();
            lbl.SetBinding(Label.TextProperty, "Number");
            Content = new StackLayout
            {
                Children = {
                    lbl
                }
            };
        }
    }

Upvotes: 1

Related Questions