Greggz
Greggz

Reputation: 1809

How to provide BindingContext to Control template

I have a template defined in App.Xaml

<ResourceDictionary>
        <ControlTemplate x:Key="HomePageTemplate">
            <Label Text="{Binding MyLabelText}"/>
        </ControlTemplate>
</ResourceDictionary>

And I use it in my Home page

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
            xmlns:local="clr-namespace:App.Converters"
            x:Class="App.Views.HomePage"
            ControlTemplate="{StaticResource HomePageTemplate}">

</ContentPage>

I set the BindingContext of my Homepage in code behind.

Now shouldn't the ControlTemplate inherit the HomePage's BindingContext ? Because I thought that was the case but my Label doesn't keep the text from MyLabelText. What's the work around to work with Bindings in these templates ?

EDIT:

Using this option

<ResourceDictionary>
        <ControlTemplate x:Key="HomePageTemplate">
            <Label Text="{TemplateBinding Parent.BindingContext.MyLabelText}"/>
        </ControlTemplate>
</ResourceDictionary>

Also does not work for me, because I use the ControlTemplatein the header of the HomePage and not inside it's body.

This works BUT IT'S NOT what I'm looking for:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
            xmlns:local="clr-namespace:App.Converters"
            x:Class="App.Views.HomePage"
            >
  <ContentView ControlTemplate="{StaticResource HomePageTemplate}" />
</ContentPage>

Upvotes: 3

Views: 2430

Answers (3)

Camilo Mendoza
Camilo Mendoza

Reputation: 206

If anyone its interested, the way this works its just adding Path after TemplateBinding, specifying BindingContext on it and then the public var name:

<ResourceDictionary>
    <ControlTemplate x:Key="HomePageTemplate">
        <Label Text="{ TemplateBinding Path=BindingContext.MyLabelText }"/>
    </ControlTemplate>
</ResourceDictionary>

Upvotes: 1

Vincent65535
Vincent65535

Reputation: 129

App.xaml should have a BindingContext. Let's call it AppViewmodel, with a namespace vm (or any other key) defined at the top of App.xaml. This AppViewmodel can be bound to from within the ControlTemplate. In this example a button (placed in a stacklayout) is bound to a command named AppCommand, which resides in AppViewmodel. When this ControlTemplate is applied in a ContentPage, it binds to the ViewModel of App.xaml, not to the VM of that particular ContentPage. Perhaps the latter is also possible, for example by choosing the right settings for RelativeSource and AncestorType, but I haven't figured that out. see also

     <ControlTemplate x:Key="HomePageTemplate">
            <StackLayout BindingContext="{Binding Source={RelativeSource TemplatedParent}}">
                    <Button 
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:AppViewModel}}, Path=AppCommand}"
                            />
            </StackLayout>
    </ControlTemplate>

Upvotes: 0

Mikolaj Kieres
Mikolaj Kieres

Reputation: 4403

With ControlTemplate controls the binding is slightly different. Have a look at these docs: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/control-templates/template-binding

Assuming that the MyLabelText property is part of the BindingContext of the parent control your code could look like this:

<ResourceDictionary>
        <ControlTemplate x:Key="HomePageTemplate">
            <Label Text="{TemplateBinding Parent.BindingContext.MyLabelText }"/>
        </ControlTemplate>
</ResourceDictionary>

Upvotes: 4

Related Questions