Home > database >  Handling both tap and scroll in CollectionView
Handling both tap and scroll in CollectionView

Time:02-03

I'm trying to handle a tap gesture so that when I tap on the CollectionView, it will display a toast. However when I add TapGestureRecognizer, it blocks me from scrolling the collection. I want that it can both scroll and tap to open something. Here's my code so far:

View:

<CollectionView 
                x:Name="eventsBox"
                ItemsSource="{Binding EventList}"
                SelectionMode="None"
                Header="Events"
                ItemsUpdatingScrollMode="KeepLastItemInView">
                <CollectionView.GestureRecognizers>
                    <TapGestureRecognizer 
                        Command="{Binding EventBoxTapCommand}"/>
                    <SwipeGestureRecognizer
                        Direction="Up"
                        Swiped="EventBoxSwiped"/>
                    <SwipeGestureRecognizer
                        Direction="Down"
                        Swiped="EventBoxSwiped"/>
                </CollectionView.GestureRecognizers>
                
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="model:Event">
                        <HorizontalStackLayout>
                            <Label Text="{Binding EventDescription}"/>
                            <Label Text="{Binding EventTime, StringFormat=' at {0}'}"/>
                        </HorizontalStackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

Code behind for Swipe gesture recognizer

    private void EventBoxSwiped(object sender, SwipedEventArgs e)
    {
        switch (e.Direction)
        {
            case SwipeDirection.Up:
                Console.WriteLine("Swiped Up"); 
                //Custon scroll here?
                break;

            case SwipeDirection.Down:
                Console.WriteLine("Swiped Down");
                //Custom scroll here?
                break;
        }
    }

I'm thinking of programmatically scroll by recognizing swipe gesture but I haven't found a way to do it. Moreover, the recognition of both tap and swipe is sometime really not responsive.

CodePudding user response:

This is a known issue tracked in Gesture Recognizer Inhibits CollectionView Scrolling.You can follow up there or create a new one on Github.

To fix the issue, you can try to add a ScrollView outside of the CollectionView like below. Also, it is recommended to add Left& Right direction of the swipe gesture in a CollectionView.

<ScrollView>
       <CollectionView> 
                <CollectionView.GestureRecognizers>
                    <TapGestureRecognizer 
                        Command="{Binding EventBoxTapCommand}"/>
                    <SwipeGestureRecognizer
                        Direction="Left"
                        Swiped="EventBoxSwiped"/>
                    <SwipeGestureRecognizer
                        Direction="Right"
                        Swiped="EventBoxSwiped"/>
                </CollectionView.GestureRecognizers>
                
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="model:Event">
                        <VerticalStackLayout>
                            <Label Text="{Binding EventDescription}"/>
                            <Label Text="{Binding EventTime, StringFormat=' at {0}'}"/>
                        </VerticalStackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
        </CollectionView>

</ScrollView>

CodePudding user response:

After Jason's comment, I came up with a work-around to achieve the effect I want. I added SelectionMode=Single to the CollectionView and changed the background color of selected item matching the theme color of the app with VisualStateManager. Therefore it appears that no item is selected but still get the tap and scroll event.

<CollectionView 
                x:Name="eventsBox"
                ItemsSource="{Binding EventList}"
                SelectionMode="Single"
                SelectionChangedCommand="{Binding SelectItemCommand}"
                Header="Events"
                ItemsUpdatingScrollMode="KeepLastItemInView">
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="model:Event">
                        <HorizontalStackLayout>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState Name="Normal" />
                                    <VisualState Name="Selected">
                                        <VisualState.Setters>
                                            <Setter Property="BackgroundColor" Value="{AppThemeBinding Dark=Black, Light=White}" />
                                        </VisualState.Setters>
                                    </VisualState>

                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Label Text="{Binding EventDescription}"/>
                            <Label Text="{Binding EventTime, StringFormat=' at {0}'}"/>
                        </HorizontalStackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

Thanks everyone for the help and information xD

  • Related