2
votes

Lets say I have a really basic class with a few properties. Eg:

public class MyClass
    {
        public MyClass()
        {
            Something = "Lorem ipsum dolor sit amet, consectetur adipiscing elit";
            OrOther = "Proin dignissim, nunc non tincidunt imperdiet, magna urna malesuada enim";
        }
        public string Something { get; set; }
        public string OrOther { get; set; }
    }

And I want to databind to this in Xaml, how would I do this? I've tried binding directly to the object, so in my Xaml page code behind:

public partial class MainPage : ContentPage
    {
        public MyClass anInstance;
        public MainPage()
        {
            InitializeComponent();
            anInstance = new MyClass();
            BindingContext = this;
        }
    }

And then in my 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"
             xmlns:local="clr-namespace:DataBindingTest"
             x:Class="DataBindingTest.MainPage">

    <Label Text="{Binding anInstance.Something}" 
           VerticalOptions="Center" 
           HorizontalOptions="Center" />

And I've also tried setting the BindingContext on a parent 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:local="clr-namespace:DataBindingTest"
             x:Class="DataBindingTest.MainPage">
    <StackLayout BindingContext="anInstance">        
        <Label Text="{Binding Something}" 
               VerticalOptions="Center" 
               HorizontalOptions="Center" />
    </StackLayout>

</ContentPage>

But it just doesn't work. I've also tried setting the bindingcontext of the page to anInstance:

 public partial class MainPage : ContentPage
    {
        public MyClass anInstance;
        public MainPage()
        {
            InitializeComponent();
            anInstance = new MyClass();
            BindingContext = anInstance;
        }
    }

And Just binding to its properties on the xaml side:

<?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:local="clr-namespace:DataBindingTest"
             x:Class="DataBindingTest.MainPage">

        <Label Text="{Binding Something}" 
               VerticalOptions="Center" 
               HorizontalOptions="Center" />

</ContentPage>

But again, all I get are blank pages. It seems that at least one of these should work. Whats the recommended way to bind to properties on a custom class like this?

edit

Taking on board @jason comments, I've also tried this:

public MyClass anInstance
        {
            get
            {
                return _anInstance;
            }
            set
            {
                _anInstance = value;
            }
        }
        private MyClass _anInstance { get; set; }
        public MainPage()
        {
            InitializeComponent();
            anInstance = new MyClass();
            BindingContext = this;
        }

And the 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"
             xmlns:local="clr-namespace:DataBindingTest"
             x:Class="DataBindingTest.MainPage">
    <StackLayout BindingContext="anInstance">
        <Label Text="{Binding Something}" 
               VerticalOptions="Center" 
               HorizontalOptions="Center" />
        <Label Text="{Binding OrOther}" 
               VerticalOptions="Center" 
               HorizontalOptions="Center" />
    </StackLayout>
</ContentPage>

But again a blank page...

Same result with:

private MyClass anInstance { get; set; }
        public MainPage()
        {
            InitializeComponent();
            anInstance = new MyClass();
            BindingContext = this;
        }

And

<?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:local="clr-namespace:DataBindingTest"
             x:Class="DataBindingTest.MainPage">
    <StackLayout BindingContext="anInstance">
        <Label Text="{Binding Something}" 
               VerticalOptions="Center" 
               HorizontalOptions="Center" />
        <Label Text="{Binding OrOther}" 
               VerticalOptions="Center" 
               HorizontalOptions="Center" />
    </StackLayout>
</ContentPage>
1
your first example doesn't work because "anInstance" is not a property. Your final example should work.Jason
Neither code shown will works. Your anInstance object must be a property. It means that it must be declared like public MyClass anInstance { get; set; }.Diego Rafael Souza
in both of your appended examples, you are setting the BindingContext in both the XAML and code behind. Pick on or the other, not both. It's confusing at best. I generally find it clearer to set it in the code behind.Jason
also, just noticed that your anInstance property is private - I believe it needs to be either public or protectedJason

1 Answers

1
votes

You're almost there. Your property needs to be public (or protected might work. Then you're setting the binding context to this. Which is fine. For the record, I am using this code:

public MyClass AnInstance { get; set; }

public MainPage()
{
    InitializeComponent();

    AnInstance = new MyClass();
    BindingContext = this;
}

Now in your XAML, you can access it's properties like this:

<?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:local="clr-namespace:DataBindingTest"
             x:Class="DataBindingTest.MainPage">
    <StackLayout>
        <Label Text="{Binding AnInstance.Something}" 
               VerticalOptions="Center" 
               HorizontalOptions="Center" />
        <Label Text="{Binding AnInstance.OrOther}" 
               VerticalOptions="Center" 
               HorizontalOptions="Center" />
    </StackLayout>
</ContentPage>

If you do not want the property name AnInstance prefix, set the binding context directly to the instance of the MyClass object, like this:

public MyClass AnInstance { get; set; }

public MainPage()
{
    InitializeComponent();

    AnInstance = new MyClass();
    BindingContext = AnInstance;
}

You can now use the properties belonging to the MyClass directly, like so: <Label Text="{Binding OrOther}" VerticalOptions="Center" HorizontalOptions="Center" />