Summary of Chapter 11. The Bindable infrastructure

In this article

Every C# programmer is familiar with C# properties. Properties contain a set accessor and/or a get accessor. They are often called CLR properties for the Common Language Runtime.

Xamarin.Forms defines an enhanced property definition called a bindable property encapsulated by the BindableProperty class and supported by the BindableObject class. These classes are related but quite distinct: The BindableProperty is used to define the property itself; BindableObject is like object in that it is a base class for classes that define bindable properties.

The Xamarin.Forms class hierarchy

The ClassHierarchy sample uses reflection to display a class hierarchy of Xamarin.Forms and demonstrate the crucial role played by BindableObject in this hierarchy. BindableObject derives from Object and is the parent class to Element from which VisualElement derives. This is the parent class to Page and View, which is the parent class to Layout:

A peek into BindableObject and BindableProperty

In the classes that derive from BindableObject many CLR properties are said to be "backed by" bindable properties. For example, the Text property of the Label class is a CLR property, but the Label class also defines a public static read-only field named TextProperty of type BindableProperty.

An application can set or get the Text property of Label normally, or the application can set the Text by calling the SetValue method defined by BindableObject with a Label.TextProperty argument. Similarly, an application can obtain the value of the Text property by calling the GetValue method, again with a Label.TextProperty argument. This is demonstrated by the PropertySettings sample.

Indeed, the Text CLR property is entirely implemented using the SetValue and GetValue methods defined by BindableObject in conjunction with the Label.TextProperty static property.

BindableObject and BindableProperty provide support for:

Giving properties default values

Storing their current values

Providing mechanisms for validating property values

Maintaining consistency among related properties in a single class

Responding to property changes

Triggering notifications when a property is about to change or has changed

Supporting data binding

Supporting styles

Supporting dynamic resources

Whenever a property that is backed by a bindable property changes, BindableObject fires a PropertyChanged event identifying the property that has changed. This event is not fired when the property is set to the same value.

Some properties are not backed by bindable properties, and some Xamarin.Forms classes — such as Span — do not derive from BindableObject. Only a class that derives from BindableObject can support bindable properties because BindableObject defines the SetValue and GetValue methods.

Because Span does not derive from BindableObject, none of its properties — such as Text — are backed by a bindable property. This is why a DynamicResource setting on the Text property of Span raises an exception in the DynamicVsStatic sample in the previous chapter. The DynamicVsStaticCode sample demonstrates how to set a dynamic resources in code using the SetDynamicResource method defined by Element. The first argument is an object of type BindableProperty.

Similarly, the SetBinding method defined by BindableObject has a first argument of type BindableProperty.

propertyName: the text name of the property (the same as the CLR property name)

returnType: the type of the CLR property

declaringType: the type of the class declaring the property

defaultValue: the property's default value

Because defaultValue is of type object, the compiler must be able to determine the default value's type. For example, if the returnType is double, the defaultValue should be set to something like 0.0 rather than just 0, or the type mismatch will trigger an exception at runtime.

It is also very common for a bindable property to include:

propertyChanged: a static method called when the property changes value. The first argument is the instance of the class whose property has been changed.