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