I have a ControlTemplate I intend to use to provide basic functionality to most all pages in my app.
Good References on the idea:
- App Theming with Xamarin.Forms Control Templates
- Simple Theme with Template Binding
- Xamarin Forms Page Templates
I came across something strange while trying to Bind a TapGestureRecognizer to an ICommand in the binding context. I was able to bind to the ICommand property in my View just fine using a Button, but not at all using a TapGestureRecognizer.
I have a back arrow image I'd like to use for backward navigation on most all pages and using an Image with a TapGestureRecognizer seems a natural fit if I can get the command to bind to my View (like it does when using a button).
The button above the frame below was an experiment to prove that the command was coded ok. Strangely the button works just fine with the exact same binding for its command, while the TGR doesn't do a thing.
Part of my ControlTemplate XAML:
<Button Grid.Row="1" HorizontalOptions="Start" VerticalOptions="Start" IsVisible="{TemplateBinding BindingContext.ShowBack}" Text ="Back" Command="{TemplateBinding BindingContext.BackNavCommand}" Margin="90,0,0,0"/>
<!-- LATE EDIT - The TGR on this Frame is doomed not to work. The whole frame should be defined BELOW the Content Presenter. Read on below for why. -->
<Frame Grid.Row="1" HorizontalOptions="Start" VerticalOptions="Start" IsVisible="{TemplateBinding BindingContext.ShowBack}" BackgroundColor="Cyan" BorderColor="Transparent" HasShadow="False" HeightRequest="50" WidthRequest="50">
<Frame.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform ="iOS" Value="5,25,0,0"/>
<On Platform ="Android" Value="5,5,0,0"/>
<On Platform ="UWP" Value="5,5,0,0"/>
</OnPlatform>
</Frame.Padding>
<Frame.GestureRecognizers>
<TapGestureRecognizer x:Name="backTapped" Command="{TemplateBinding BindingContext.BackNavCommand}" />
</Frame.GestureRecognizers>
<Image x:Name="backImage" Source="back.png" Aspect="AspectFit" HeightRequest="20" WidthRequest="30" VerticalOptions="Center" HorizontalOptions="Center" InputTransparent="True"/>
</Frame>
<ContentPresenter Grid.Row="1"/>
I set the backgroundcolor of the Frame containing the image Cyan to make sure my tap region was showing up. It is clearly there, but tapping it never activates the TGR and the associated command I've set for it to fire.
Note: My content to fill in the ContentPresenter has a transparent background, to show the main page's backing image. This is key to this scenario, as it's tricky to tell what is infront of what.