Forum Xamarin.Forms

TemplateBindings in ControlTemplate doesn't work

I have tried to follow the following example but with no luck:
https://developer.xamarin.com/guides/xamarin-forms/templates/control-templates/template-binding/

I have created a controltemplate that I want to bind with commands in my viewmodel.

ViewModel
public ICommand VoteYesCommand { get; set; } public ICommand VoteNoCommand { get; set; }

Xaml Page
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="VoteKMD.Features.PollPage.Page.PollPage" x:Name="PollPageReferenceName" xmlns:converters="clr-namespace:VoteKMD.Converters;assembly=VoteKMD" ControlTemplate="{StaticResource FooterTemplate}"> <StackLayout> <Label IsVisible="{Binding DescriptionLabelIsVisible}" HorizontalOptions="Center" FontSize="Small" Text="{Binding SelectedPollItem.Description}" /> </StackLayout> </ContentPage>

ControlTemplate
<Application.Resources> <ResourceDictionary> <ControlTemplate x:Key="FooterTemplate"> <StackLayout Orientation="Vertical" AbsoluteLayout.LayoutBounds="1,1,1,1" AbsoluteLayout.LayoutFlags="All"> <StackLayout VerticalOptions="StartAndExpand"> <ContentPresenter /> </StackLayout> <StackLayout VerticalOptions="End"> <Button Text="Yes" Command="{TemplateBinding VoteYesCommand}"/> <Button Text="No" Command="{TemplateBinding VoteNoCommand}"/> </StackLayout> </StackLayout> </ControlTemplate> </ResourceDictionary> </Application.Resources>

The application and the template works fine but the bindings on the two buttons in the controltemplate doesnt work. I have set breakpoints inside the two commands and the methods aren't reached.
I have tried to do {TemplateBinding Parent.VoteNoCommand} as the example suggests but the "Parent" type is unknown.
Using "ContentView" inside the ContentPage doesnt seem to work either.

Also the linked example is 3 months old and I am running forms 2.2.0.45. Is there something new to this that they haven't documented?

Best Answer

Answers

  • tyjentyjen USMember ✭✭

    I'm also having issues binding within a ControlTemplate. No one seems to know how it works :(

  • CasperNybroeCasperNybroe USMember

    Would be nice if we could get some Xamarin folks on this issue. :)

  • CasperNybroeCasperNybroe USMember

    Hi @LesBrown, thank you for your suggestion on the solution. I had it working in the code behind with your solution but I cannot figure out how to get it working in XAML?

  • PaulCharltonPaulCharlton GBMember ✭✭

    Did you get this to work? Looking at your example it looks like it should work.

    I've also ran into a similar problem and fixed bodged it by calling OnPropertyChanged in the OnBindingContextChanged method. ie:

            protected override void OnBindingContextChanged()
            {
                base.OnBindingContextChanged();
    
                OnPropertyChanged(nameof(BindingContext));
            }        
    
    
  • CasperNybroeCasperNybroe USMember

    Hi @PaulCharlton , yes I had it working with the codebehind setup. But not in xaml. :)

  • swastiswasti INMember ✭✭

    Anybody found out how to work it in xaml ?

  • JESUSPADILLA.5020JESUSPADILLA.5020 USMember
    edited September 2017

    I get work it on xaml
    ViewModel
    #region Commands public ICommand BackCommand { get; internal set; } #endregion ... BackCommand = new RelayCommand(async () => await CallBack(),() => true, this);
    App.xaml
    <ControlTemplate x:Key="MainPageTemplate"> <Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" ColumnSpacing="0"> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <BoxView BackgroundColor="{StaticResource DinexPink}" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="5"/> <Button x:Name="btnBack" Image="ic_left_arrow.png" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="1" BackgroundColor="{StaticResource DinexPink}" BorderColor="{StaticResource DinexPink}" BorderRadius="0" Command="{TemplateBinding Parent.BindingContext.BackCommand}" /> <Image Grid.Column="2" Grid.Row="0" Grid.ColumnSpan="1" Source="icon.png" Aspect="AspectFit" /> <ContentPresenter VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="5"/> </Grid> </ControlTemplate>
    My content page
    <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="DinexApp.Views.SearchAgentView" BackgroundColor="{StaticResource BackgroundColor}"> <ContentView x:Name="contentView" ControlTemplate="{StaticResource MainPageTemplate}"> </ContentView> </ContentPage>

    Hope can help !

  • GaetanFGaetanF USMember ✭✭✭

    The type of binding to use is TemplateBinding. It targets a Parent property which is the ControlPresenter aka the Page it is attached to.

    In short, do in XAML:

    • {TemplateBinding Parent.MyPageProperty} to bind to the bindable property MyPageProperty of the parent's page.
    • {TemplateBinding Parent.BindingContext.MyViewModelProperty} to bind to the bindable property MyViewModelProperty of the parent's page bindingcontext which is a view model if you follow MVVM.

    The second case is the XAML equivalent code of @LesBrown solution (well, almost if you add Mode=TwoWay)
    More documentation here

Sign In or Register to comment.