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

  • Question

  • User33535 posted

    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!

    Wednesday, April 15, 2020 3:29 PM

Answers

  • User369979 posted

    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.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, April 16, 2020 7:26 AM
  • User369979 posted

    Yes, it is. A normal class with normal CLR properties meets your situation here.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, April 17, 2020 1:36 AM

All replies

  • User369979 posted

    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.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, April 16, 2020 7:26 AM
  • User33535 posted

    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 (

    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.

    Friday, April 17, 2020 1:31 AM
  • User369979 posted

    Yes, it is. A normal class with normal CLR properties meets your situation here.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, April 17, 2020 1:36 AM