Home > Software engineering >  Xamarin Forms TapGestureRecognizer blocks actual tapping
Xamarin Forms TapGestureRecognizer blocks actual tapping

Time:10-22

I have stacklayout inside of collectionview and I want to tap on stacklayout element to perform a binded command. The moment I add TapGestureRecognizer to the stacklayout - Stacklayout stops to respond to touches (I can still scroll it though) and binded command doesn't fire:

<CollectionView ItemsSource="{Binding ResponseResponses}" SelectionMode="Single" >
                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <StackLayout>
                                <StackLayout.GestureRecognizers>
                                    <TapGestureRecognizer Command="{Binding SearchCommand}" NumberOfTapsRequired="1"/>
                                </StackLayout.GestureRecognizers>
                                <Label Text="{Binding Username, StringFormat=User: {0}}" />
                                <Label Text="{Binding FileCount, StringFormat=Files: {0}}" />
                                <BoxView   HeightRequest="1"
                                           BackgroundColor="LightGray"
                                           VerticalOptions="End"/>      
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>

So without GestureRecognizers - selection on elements of stacklayout works, with - doesn't. If I add GestureRecognizers to label (for example), then touch gets blocked on that label.

Btw {Binding SearchCommand} is working by itself, it is binded to other button in view, so it is probably no the reason.

So, what I'm doing wrong here?

CodePudding user response:

So, as I found here: CollectionView Tips

Keep in mind that when working in the ItemTemplate the BindingContext is the item itself and not that of the ContentPage. If your command exists on the item, then you’re all set. However if you wish to route this binding to a command on your ContentPage‘s view model as in this example you can use the newly supported RelativeSource.

So you have to use bindings like that:

<CollectionView.ItemTemplate>
    <DataTemplate>
        <views:ResultViewA>
            <views:ResultViewA.GestureRecognizers>
                <TapGestureRecognizer
                    Command="{Binding 
                        Source={RelativeSource 
                        AncestorType={x:Type vm:FlightResultsViewModel}}, 
                            Path=GoToDetailsCommand}"
                    CommandParameter="{Binding .}"/>
            </views:ResultViewA.GestureRecognizers>
        </views:ResultViewA>
    </DataTemplate>
</CollectionView.ItemTemplate>

In my case it now look like this:

<StackLayout>
       <StackLayout.GestureRecognizers>
                <TapGestureRecognizer
                       Command="{Binding 
                       Source={RelativeSource 
                       AncestorType={x:Type viewmodels:SearchViewModel}}, 
                       Path=SearchCommand}"
                       CommandParameter="{Binding .}"/>
       </StackLayout.GestureRecognizers>
       <Label Text="{Binding Username, StringFormat=User: {0}}"/>
       <Label Text="{Binding FileCount, StringFormat=Files: {0}}"/>
       <BoxView   HeightRequest="1"
                  BackgroundColor="LightGray"
                  VerticalOptions="End" InputTransparent="True"/>
  • Related