locked
Simple binding not working - what did I not understand? RRS feed

  • Question

  • User209994 posted

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

    } `

    Sunday, April 17, 2016 6:37 AM

Answers

  • User120969 posted

    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.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Sunday, April 17, 2016 11:11 AM
  • User103165 posted

    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!

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Sunday, April 17, 2016 11:38 AM
  • User120969 posted

    @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.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Sunday, April 17, 2016 2:59 PM

All replies

  • User120969 posted

    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.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Sunday, April 17, 2016 11:11 AM
  • User103165 posted

    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!

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Sunday, April 17, 2016 11:38 AM
  • User209994 posted

    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.

    Sunday, April 17, 2016 2:49 PM
  • User120969 posted

    @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.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Sunday, April 17, 2016 2:59 PM
  • User395589 posted

    @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

    Wednesday, July 15, 2020 9:56 AM
  • User395589 posted

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

    Wednesday, July 15, 2020 10:53 AM
  • User209994 posted

    @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.

    Sunday, July 19, 2020 5:06 AM
  • User379521 posted

    Hi, Object reference in binding context within xaml is not working. For example Label Text="{Binding MyViewModel.User.FirstName, StringFormat='{0:F0}'}"
    FontSize="14" HorizontalOptions="Center" HorizontalTextAlignment="Start" VerticalTextAlignment="Center"

    Binding MyViewModel.User.FirstName isn't displaying even though there is data.

    Sunday, February 28, 2021 6:50 PM