Search code examples
xamarinxamarin.formsbindingdatatemplate

Xamarin Forms: Call Command of ViewModel from DataTemplate


I am stuck on a binding problem here.

I created a bindable layout which is inside a control template:

<ContentView x:Name="SettingsMenu" ControlTemplate="{StaticResource HeaderTemplate}" AbsoluteLayout.LayoutBounds="0.5,0.5,1,1" 
AbsoluteLayout.LayoutFlags="All">               
    <ScrollView Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">                   
        <StackLayout x:Name="SettingsStack" BindableLayout.ItemsSource="{Binding Settings}" BindableLayout.ItemTemplateSelector="{StaticResource SettingsSelectorTemplate}" Orientation="Vertical" Spacing="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />           
    </ScrollView>        
</ContentView>

What I want to do is call a command inside the view model. The call is inside a item template selector as a resource dictionary inside App.xml

<ResourceDictionary>
    <DataTemplate x:Key="PlaceholderSettingsTemplate">
        ### SOME STUFF
     </DataTemplate>
     <DataTemplate x:Key="HeaderSettingsTemplate">
             ### SOME STUFF
         <Grid ...>
             <Grid.GestureRecognizers>
                 <TapGestureRecognizer Tapped="ButtonClick" Command="{Binding BindingContext.SettingsTap, Source={x:Reference SettingsPage}}" CommandParameter="{Binding}" />  ########## <--------- WHAT TO USE FOR SOURCE?
             </Grid.GestureRecognizers>
         </Grid>
     </DataTemplate>
     <data:SettingsSelector x:Key="SettingsSelectorTemplate" Placeholder="{StaticResource PlaceholderSettingsTemplate}" Heading="{StaticResource HeaderSettingsTemplate}" Content="{StaticResource ContentSettingsTemplate}" />
</ResourceDictionary>

Before I moved it inside a resource dictionary in the App.xml file, I simply used the x:Name of the Parent Contentview. But: I can't reference it by name anymore because I moved it into a resource dictionary inside App.xml.

Now, the answer may be trivial but I just can't find a solution.

Any help is appreciated.

Kind regards


Solution

  • You can find the SettingsStack StackLayout using the data template's Grid which wraps all the content. Since the SettingsStack has the same binding context as the parent content view, you can access the binding context in App.cs like:

    <DataTemplate x:Key="HeaderSettingsTemplate">
        <!--### SOME STUFF-->
        <Grid x:Name="ParentGrid">
            <Grid.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding Parent.BindingContext.SettingsTap, Source={x:Reference ParentGrid}}" CommandParameter="{Binding}" />
            </Grid.GestureRecognizers>
        </Grid>
    </DataTemplate>
    

    The ParentGrid's parent is SettingsStack on your current page.