Skip to content

ControlTemplate not propagating the BindingContext correctly if set through Binding #22607

@strajk-

Description

@strajk-

Description

It's a repeat of the Issue #12470 that was supposedly fixed with the Pull #12536 except in my case the propagation doesn't seem to work correctly if the ControlTemplate is set through Binding.

Steps to Reproduce

  1. Create a Template without a BindingContext, add it as a Resource in your ContentPage
<ContentPage.Resources>
    <ResourceDictionary>
         <ControlTemplate  x:Key="String_Template" >
             <Entry Text="{Binding Value, Mode=TwoWay}"/>
         </ControlTemplate>
    </ResourceDictionary>
</ContentPage.Resources>
  1. A Property to Bind to that handles the ControlTemplate swapping
public static readonly BindableProperty TypeTemplateProperty = BindableProperty.Create(
    nameof(TypeTemplate),
    typeof(ControlTemplate),
    typeof(ContentPage),
    defaultValue: null,
    defaultBindingMode: BindingMode.OneWay);

public ControlTemplate TypeTemplate
{
    get => (ControlTemplate)GetValue(TypeTemplateProperty);
    set => SetValue(TypeTemplateProperty, value);
}
  1. Add a ContentView that will show the Template set in TypeTemplate
<Grid BindingContext="{Binding Source={RelativeSource Mode=FindAncestor,AncestorType={x:Type ContentPage}}}">
    <ContentView ControlTemplate="{Binding TypeTemplate}"/>
</Grid>
  1. Some logic to set our TypeTemplate
Resources.TryGetValue("String_Template", out object template);
if (template != null && template is ControlTemplate cTemplate) {
    TypeTemplate = cTemplate;
}
  1. Value Property that we want to show in our ControlTemplate
public object Value { get; set; } = "Test";

Link to public reproduction project repository

No response

Version with bug

8.0.10 SR3

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

Android, I was not able test on other platforms

Affected platform versions

API 34 (Android 14.0) - Didn't test others

Did you find any workaround?

Adding the BindingContext on the Control that's defined inside the ControlTemplate to "renew" the BindingContext fixes it.

<ControlTemplate  x:Key="String_Template" >
    <Entry Text="{Binding Value, Mode=TwoWay}" BindingContext="{Binding BindingContext, Source={RelativeSource Mode=TemplatedParent}}"/>
</ControlTemplate>

It also works if I were to set the ControlTemplate as a StaticResource like this:

<Grid BindingContext="{Binding Source={RelativeSource Mode=FindAncestor,AncestorType={x:Type ContentView}}}">
    <ContentView ControlTemplate="{StaticResource String_Template}"/>
</Grid>

But that defeats the purpose of being able to dynamically switch between ControlTemplates without extra C# code.

Relevant log output

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-layoutStackLayout, GridLayout, ContentView, AbsoluteLayout, FlexLayout, ContentPresenterarea-xamlXAML, CSS, Triggers, Behaviorsfixed-in-9.0.21platform/androidt/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions