data-bindingmauicustom-controlscontentviewcompiled-bindings

MAUI Compiled Bindings in ContentViews


I came across this while reading the MS documentation for compiled bindings and it has confused me now with how to do data binding on ContentViews for custom controls:

Important

Compiled bindings are disabled for any binding expressions that define the Source property. This is because the Source property is always set using the x:Reference markup extension, which can't be resolved at compile time.

In addition, compiled bindings are currently unsupported on multi-bindings.

My question concerns ContentViews where you are binding to a BindableProperty on the control.

The (recommended) approach in the documentation involves setting the binding context for the control using x:Reference as below:

<ContentView
    x:Class="LoadTimeTestingWithAsync.Controls.DriverCard"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Name="driverCard">
    <VerticalStackLayout BindingContext="{x:Reference driverCard}">
        <Label
            SemanticProperties.HeadingLevel="Level1"
            Style="{StaticResource Headline}"
            Text="Driver Details" />
        <Label
            SemanticProperties.HeadingLevel="Level1"
            Style="{StaticResource SubHeadline}"
            Text="{Binding DriverInfo.FullName}" />
    </VerticalStackLayout>
</ContentView>

Does this mean that compiled bindings are not being used for the 2nd label bindings because the BindingContext is set on the StackLayout using x:Reference?

Or is it only when specifying source as below:

<ContentView
    x:Class="LoadTimeTestingWithAsync.Controls.DriverCard"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Name="driverCard">
    <VerticalStackLayout>
        <Label
            SemanticProperties.HeadingLevel="Level1"
            Style="{StaticResource Headline}"
            Text="Driver Details" />
        <Label
            SemanticProperties.HeadingLevel="Level1"
            Style="{StaticResource SubHeadline}"
            Text="{Binding DriverInfo.FullName, Source={x:Reference driverCard}}" />
    </VerticalStackLayout>
</ContentView>

Both are using x:Reference, but only the second is using Source.

Is it the source prop itself or the x:Reference that means compiled bindings won't be used? The blue notification sort of implies that the x:Reference is the reason with the way it is worded, but maybe if it's used to specify a BindingContext, then any binding below that will still use compiled?

I suppose following the documented examples is probably the best way to go but I just wanted to double check.


Solution

  • As the doc says,

    Compiled bindings are disabled for any binding expressions that define the Source property. This is because the Source property is always set using the x:Reference markup extension, which can't be resolved at compile time.

    So if doing bindings with x:Reference, the data bindings won't be pre-compiled (while the rest of the XAML will be pre-compiled).

    By the way, I haven't seen any x:DataType set on any VisualElement, so compiled bindings won't be used anyway.

    Actually, you may check the generated output or test it, e.g.

    Text="{Binding WrongPropertyName, Source={x:Reference driverCard}}"  x:DataType="local:CustomView"
    

    Like above, if you use x:Reference , even though you set the x:DataType on Label or any parent control , still there's no compile-time validation of binding expressions. You can only find data binding not working until runtime. Without x:Reference, you may see compile-time validation.