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.

Data binding doesn't work without CLR property (with only BindableProperty)

EugeneVeselovEugeneVeselov USMember ✭✭
edited April 15 in Xamarin.Forms

I have a BindableObject without any CLR properties. All properties are declared as BindableProperty. Binding expressions seem not working in this case.

My c# code

class Record: BindableObject {
    private static BindableProperty TitleProperty = BindableProperty.Create("Title", typeof(string), typeof(Record));
    public Record() {
        this.SetValue(TitleProperty, "MyRecord");
    }
    // Note: no CLR property declaration (commented out)
    // public string Title { get { return (string)this.GetValue(TitleProperty); } }
}

My binding expression in XAML code (assuming that BindingContext is set to my Record object):

<Label Text="{Binding Title}" ...

Result: no text appeared in the Label.

Binding works fine after adding CLR property declaration "public string Title { get { return (string)this.GetValue(TitleProperty); } }".

My question is why CLR property is required for binding to work. I thought that declaring BindableProperty and using GetValue/SetValue is sufficient for that.
Am I missing something?

For some reasons I need to avoid CLR property declarations in my project, so this is blocking for me. Apart from that this behavior puzzles my overal understanding of how data binding works in Xamarin.

Thanks!

Best Answers

  • LandLuLandLu Member, Xamarin Team Xamurai
    Accepted Answer

    This is the grammar of bindable property:
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/bindable-properties#create-a-bindable-property
    Bindable property is used to add an extra property of a custom control. Therefore, we could use this property directly in xaml to consume the binding features.
    i.e. if you want to add a custom property in your custom label you could define it like:

    public class CustomLabel : Label
    {
        public static BindableProperty TitleProperty = BindableProperty.Create("Title", typeof(string), typeof(Label));
    
        public string Title 
        { 
            get => (string)this.GetValue(TitleProperty);
            set => SetValue(TitleProperty, value);
        }
    }
    // xml
    <local:CustomLabel Title="{Binding ...}"/>
    

    We need a normal property to be the accessor of the bindable so that binding could work in xaml.
    I think you misunderstood the usage of bindable property. It is not the binding path of your property. It's the binding element itself.
    Take a look at the text property definition:

    This is why we can use Text in xaml for binding.
    I think what you really need here is a normal class as the binding context of your controls:
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm
    There's no need to define bindable properties in the view model. A normal property can be used as the binding path.

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai
    Accepted Answer

    This is the grammar of bindable property:
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/bindable-properties#create-a-bindable-property
    Bindable property is used to add an extra property of a custom control. Therefore, we could use this property directly in xaml to consume the binding features.
    i.e. if you want to add a custom property in your custom label you could define it like:

    public class CustomLabel : Label
    {
        public static BindableProperty TitleProperty = BindableProperty.Create("Title", typeof(string), typeof(Label));
    
        public string Title 
        { 
            get => (string)this.GetValue(TitleProperty);
            set => SetValue(TitleProperty, value);
        }
    }
    // xml
    <local:CustomLabel Title="{Binding ...}"/>
    

    We need a normal property to be the accessor of the bindable so that binding could work in xaml.
    I think you misunderstood the usage of bindable property. It is not the binding path of your property. It's the binding element itself.
    Take a look at the text property definition:

    This is why we can use Text in xaml for binding.
    I think what you really need here is a normal class as the binding context of your controls:
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm
    There's no need to define bindable properties in the view model. A normal property can be used as the binding path.

  • EugeneVeselovEugeneVeselov USMember ✭✭

    Thank you, https://forums.xamarin.com/profile/LandLu for the explanation.

    Let me rephrase how I understood you (and feel free to correct). Bindable property IS NOT needed if you need to use it as a source of binding ( <Label Text="{Binding MYPROPERTY}"). For this purpose a regular CLR property would be sufficient. BindableProperty is needed to use it as a target of binding(<Lablel MYPROPERTY="{Binding text}").

    My scenario was the former, so I did need a CLR property. Adding BindableProperty was not needed at all. That's why when I removed the CLR property the binding stopped working.

Sign In or Register to comment.