Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Simple binding not working - what did I not understand?

BananaTieBananaTie DKMember ✭✭

Hello

Learning about Xamarin.Forms is exciting - but for the past many hours I have been working a problem:
It seems that I forgot some very basic knowledge of how to bind a variable to a XAML item (like a label). Could someone please tell me what I am missing to make this simple binding work? I believe I had something like this working days ago, but seem to have lost the working example.

Please tell me what I am missing in this simple "Hello World!" example. As seen in the attached picture, I am missing "World!".

file: BindingTest.cs
`
using System;
using Xamarin.Forms;

namespace BindingTest
{
public class App : Application
{
public App ()
{
// The root page of your application
MainPage = new MyPage(); // Show my simple page when APP is starting
}

    protected override void OnStart ()
    {
        // Handle when your app starts
    }

    protected override void OnSleep ()
    {
        // Handle when your app sleeps
    }

    protected override void OnResume ()
    {
        // Handle when your app resumes
    }
}

}
`

File: MyPage.xaml
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="BindingTest.MyPage"> <ContentPage.Content> <StackLayout HorizontalOptions="Center" VerticalOptions="Center"> <Label Text="Hello"/> <!-- This label should be visible just below 'Hello' - binding the 'randomText' to the variable in MyPage.xaml.cs --> <Label Text="{Binding randomText}"/> </StackLayout> </ContentPage.Content> </ContentPage>

File: MyPage.xaml.cs
`
using System;
using System.Collections.Generic;

using Xamarin.Forms;

namespace BindingTest
{
public partial class MyPage : ContentPage
{
public string randomText { get; set; }

    public MyPage ()
    {
        randomText = "World!";
        InitializeComponent ();
    }
}

}
`

Best Answers

  • Matthew.4307Matthew.4307 USMember ✭✭✭
    edited April 2016 Accepted Answer

    The best approach is MVVM which means at some point you need to set Page.BindingContext = YourViewModel and that has the property RandomText which gets bound to the label.

    The other option, if you want to bind to the Page is to set Page.BindingContext = this (where this = page). - Should work?

    Final option is that you set the BindingContext of the label = Page.

  • GeraldVersluisGeraldVersluis NLUniversity ✭✭✭✭
    Accepted Answer

    Like @Matthew.4307 says, you need to set the BindingContext of your page.

    To make the code you are showing work, simply do this;

    public MyPage ()
        {
            InitializeComponent ();
            randomText = "World!";
    
            BindingContext = this;
        }
    

    Your text should display now.
    Another, more common method, is to bind to a ViewModel, so then you have to create another object and set that as your BindingContext.
    A great way do to so automagically is by using a MVVM framework. A very good one by @MichaelRidland is the FreshMvvm framework. I've made a blogpost about it here.

    And of course if you have any more question just post them here or message me directly :smile: Good luck!

  • Matthew.4307Matthew.4307 USMember ✭✭✭
    edited April 2016 Accepted Answer

    @BananaTie said:
    Hi GeraldVersluis and Matthew4307

    That was perfect - it worked right away. That was the missing link (or rather: 'Binding').

    I understand the principle of MVVM and how to split the model from the view with a ViewModel and the code I provided was only to show the minimum code that could reproduce my issue. When that is said, I am not an expert in the design pattern yet and I am grateful for your input.

    @Matthew.4307 : You mention Page.BindingContext - Could you show me an example of how to use it in context of my tiny example? I get a feeling it is from the XAML definition you set it up, but I fail to make it work.

    Again: Thank you for your effort and time.

    @GeraldVersluis showed how to explicitly set the binding context on a page.

    The default behaviour is that any control on a page binds to the BindingContext of the Page, though if your page doesn't have Binding Context and you want to access a property on it you can do so this way in XAML.

    Firstly you add a name to your page as follows
    ContentPage x:Name="parent"

    This allows you to reference this from any controls in the XAML.

    Next you set the Binding Context of the label to be "parent" rather than the Binding Context on the page.

    Label BindingContext="{x:Reference parent}" Text="{Binding Path=RandomText}"

    That means label looks for a property named RandomText on the object named "parent".

    I'm not suggesting this is the normal way you would achieve the results you want, but it's another option.

Answers

  • Matthew.4307Matthew.4307 USMember ✭✭✭
    edited April 2016 Accepted Answer

    The best approach is MVVM which means at some point you need to set Page.BindingContext = YourViewModel and that has the property RandomText which gets bound to the label.

    The other option, if you want to bind to the Page is to set Page.BindingContext = this (where this = page). - Should work?

    Final option is that you set the BindingContext of the label = Page.

  • GeraldVersluisGeraldVersluis NLUniversity ✭✭✭✭
    Accepted Answer

    Like @Matthew.4307 says, you need to set the BindingContext of your page.

    To make the code you are showing work, simply do this;

    public MyPage ()
        {
            InitializeComponent ();
            randomText = "World!";
    
            BindingContext = this;
        }
    

    Your text should display now.
    Another, more common method, is to bind to a ViewModel, so then you have to create another object and set that as your BindingContext.
    A great way do to so automagically is by using a MVVM framework. A very good one by @MichaelRidland is the FreshMvvm framework. I've made a blogpost about it here.

    And of course if you have any more question just post them here or message me directly :smile: Good luck!

  • BananaTieBananaTie DKMember ✭✭

    Hi GeraldVersluis and Matthew4307

    That was perfect - it worked right away. That was the missing link (or rather: 'Binding').

    I understand the principle of MVVM and how to split the model from the view with a ViewModel and the code I provided was only to show the minimum code that could reproduce my issue. When that is said, I am not an expert in the design pattern yet and I am grateful for your input.

    @Matthew.4307 : You mention Page.BindingContext - Could you show me an example of how to use it in context of my tiny example? I get a feeling it is from the XAML definition you set it up, but I fail to make it work.

    Again: Thank you for your effort and time.

  • Matthew.4307Matthew.4307 USMember ✭✭✭
    edited April 2016 Accepted Answer

    @BananaTie said:
    Hi GeraldVersluis and Matthew4307

    That was perfect - it worked right away. That was the missing link (or rather: 'Binding').

    I understand the principle of MVVM and how to split the model from the view with a ViewModel and the code I provided was only to show the minimum code that could reproduce my issue. When that is said, I am not an expert in the design pattern yet and I am grateful for your input.

    @Matthew.4307 : You mention Page.BindingContext - Could you show me an example of how to use it in context of my tiny example? I get a feeling it is from the XAML definition you set it up, but I fail to make it work.

    Again: Thank you for your effort and time.

    @GeraldVersluis showed how to explicitly set the binding context on a page.

    The default behaviour is that any control on a page binds to the BindingContext of the Page, though if your page doesn't have Binding Context and you want to access a property on it you can do so this way in XAML.

    Firstly you add a name to your page as follows
    ContentPage x:Name="parent"

    This allows you to reference this from any controls in the XAML.

    Next you set the Binding Context of the label to be "parent" rather than the Binding Context on the page.

    Label BindingContext="{x:Reference parent}" Text="{Binding Path=RandomText}"

    That means label looks for a property named RandomText on the object named "parent".

    I'm not suggesting this is the normal way you would achieve the results you want, but it's another option.

  • kamranmasudkamranmasud Member ✭✭

    @GeraldVersluis said:
    Like @Matthew.4307 says, you need to set the BindingContext of your page.

    To make the code you are showing work, simply do this;

    public MyPage ()
        {
            InitializeComponent ();
            randomText = "World!";
    
            BindingContext = this;
        }
    

    Your text should display now.
    Another, more common method, is to bind to a ViewModel, so then you have to create another object and set that as your BindingContext.
    A great way do to so automagically is by using a MVVM framework. A very good one by @MichaelRidland is the FreshMvvm framework. I've made a blogpost about it here.

    And of course if you have any more question just post them here or message me directly :smile: Good luck!

    Brother i am showing products on my home page...The products are coming from api..When i start the application it does not show anything but when i press ctrl+s on home page file it shows products..I dont know why it is happening?Plz help

  • kamranmasudkamranmasud Member ✭✭

    @Matthew.4307 @GeraldVersluis Do you know any solution?

  • BananaTieBananaTie DKMember ✭✭

    @kamranmasud not knowing your exact code, it does sound like you are missing an event to handle the update of the screen when the API data are ready for display... something in the line of what is talked about here.

Sign In or Register to comment.