Xamarin.forms: [Bug] CollectionView Selection Changed (or item tapped) not working using SwipeView on Android

Created on 27 Dec 2019  路  14Comments  路  Source: xamarin/Xamarin.Forms

Description

If I use SwipeView in a CollectionView ItemTemplate, then, SelectionChanged and Item Tapped is not working.

Steps to Reproduce

Having the following XAML
```
Margin="0,16,0,0"
Grid.Row="1"
SelectionMode="Single">







                                </SwipeItemView>
                            </SwipeItems>
                        </SwipeView.LeftItems>
                        <SwipeView.RightItems>
                            <SwipeItems Mode="Execute">
                                <SwipeItemView BackgroundColor="White"
                                               VerticalOptions="Center">
                                    <Label TextColor="Red"
                                           VerticalOptions="Center"
                                           Text="Test2"
                                           VerticalTextAlignment="Center"
                                           Padding="10" />
                                </SwipeItemView>
                            </SwipeItems>
                        </SwipeView.RightItems>
                        <Frame Padding="4"
                               Margin="0"
                               BackgroundColor="LightGray">
                            <Frame.GestureRecognizers>
                                <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1" />
                            </Frame.GestureRecognizers>

                            <Label TextColor="Black"
                                   FontSize="24"
                                   FontAttributes="Bold"
                                   Text="I'm an Item" />
                        </Frame>
                    </SwipeView>
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

```
TapGestureRecognizer_Tapped_1 never gets called, neither if you add a SelectionChanged event in CollectionView

Expected Behavior

tap event should get called, selectionChanged event should get called

Actual Behavior

TapGestureRecognizer_Tapped_1 never gets called, neither if you add a SelectionChanged event in CollectionView

Basic Information

  • Version with issue: 4.4.0.991265
  • Last known good version:
  • IDE: Visual Studio Community 2017 Version 15.9.17
  • Platform Target Frameworks:

    • Android: 8.1
collectionview swipeview 6 in-progress Android bug

Most helpful comment

I've found a workaround, if you define a gesture recognaizer in the SwipeView, (this gesture works), and there you set the selectedItem as the item trigering the swipeView tap,then you have it , it's a bit ugly but works

<CollectionView ItemsSource="{Binding Items}"
                      x:Name="MyCollectionView"
                      Margin="0,16,0,0"
                      Grid.Row="1"
                      SelectionMode="Single">
          <CollectionView.ItemTemplate>
              <DataTemplate>
                  <Grid Margin="6">
                      <SwipeView>
                         <SwipeView.GestureRecognizers>
                            <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1"/> 
                        </SwipeView.GestureRecognizers>
                          <SwipeView.LeftItems>
                              <SwipeItems Mode="Execute">
                                  <SwipeItemView BackgroundColor="White">
                                      <Label TextColor="Blue"
                                             VerticalOptions="Center"
                                             Text="Test1"
                                             VerticalTextAlignment="Center"
                                             Padding="10" />

                                  </SwipeItemView>
                              </SwipeItems>
                          </SwipeView.LeftItems>
                          <SwipeView.RightItems>
                              <SwipeItems Mode="Execute">
                                  <SwipeItemView BackgroundColor="White"
                                                 VerticalOptions="Center">
                                      <Label TextColor="Red"
                                             VerticalOptions="Center"
                                             Text="Test2"
                                             VerticalTextAlignment="Center"
                                             Padding="10" />
                                  </SwipeItemView>
                              </SwipeItems>
                          </SwipeView.RightItems>
                          <Frame Padding="4"
                                 Margin="0"
                                 BackgroundColor="LightGray">
                              <Frame.GestureRecognizers>
                                  <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1" />
                              </Frame.GestureRecognizers>

                              <Label TextColor="Black"
                                     FontSize="24"
                                     FontAttributes="Bold"
                                     Text="I'm an Item" />
                          </Frame>
                      </SwipeView>
                  </Grid>
              </DataTemplate>
          </CollectionView.ItemTemplate>
      </CollectionView>

.xaml.cs =>

private void TapGestureRecognizer_Tapped_1(object sender, EventArgs e)
{
    MyCollectionView.SelectedItem = (sender as SwipeView).BindingContext;
}

All 14 comments

I've found a workaround, if you define a gesture recognaizer in the SwipeView, (this gesture works), and there you set the selectedItem as the item trigering the swipeView tap,then you have it , it's a bit ugly but works

<CollectionView ItemsSource="{Binding Items}"
                      x:Name="MyCollectionView"
                      Margin="0,16,0,0"
                      Grid.Row="1"
                      SelectionMode="Single">
          <CollectionView.ItemTemplate>
              <DataTemplate>
                  <Grid Margin="6">
                      <SwipeView>
                         <SwipeView.GestureRecognizers>
                            <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1"/> 
                        </SwipeView.GestureRecognizers>
                          <SwipeView.LeftItems>
                              <SwipeItems Mode="Execute">
                                  <SwipeItemView BackgroundColor="White">
                                      <Label TextColor="Blue"
                                             VerticalOptions="Center"
                                             Text="Test1"
                                             VerticalTextAlignment="Center"
                                             Padding="10" />

                                  </SwipeItemView>
                              </SwipeItems>
                          </SwipeView.LeftItems>
                          <SwipeView.RightItems>
                              <SwipeItems Mode="Execute">
                                  <SwipeItemView BackgroundColor="White"
                                                 VerticalOptions="Center">
                                      <Label TextColor="Red"
                                             VerticalOptions="Center"
                                             Text="Test2"
                                             VerticalTextAlignment="Center"
                                             Padding="10" />
                                  </SwipeItemView>
                              </SwipeItems>
                          </SwipeView.RightItems>
                          <Frame Padding="4"
                                 Margin="0"
                                 BackgroundColor="LightGray">
                              <Frame.GestureRecognizers>
                                  <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1" />
                              </Frame.GestureRecognizers>

                              <Label TextColor="Black"
                                     FontSize="24"
                                     FontAttributes="Bold"
                                     Text="I'm an Item" />
                          </Frame>
                      </SwipeView>
                  </Grid>
              </DataTemplate>
          </CollectionView.ItemTemplate>
      </CollectionView>

.xaml.cs =>

private void TapGestureRecognizer_Tapped_1(object sender, EventArgs e)
{
    MyCollectionView.SelectedItem = (sender as SwipeView).BindingContext;
}

I am actually facing the same exact issue described by psp589. I will try that workaround.

Sadly for me the workaround psp589 shared above, did not work.

`


FontFamily="{DynamicResource MaterialFontFamily}"
Glyph="{StaticResource Settings}"
Size="32"
Color="{StaticResource GreyColor}" />






HeightRequest="100">

Command="{Binding OnNavigateToVisitorsCommand}"
NumberOfTapsRequired="1"/>


Mode="Reveal">

WidthRequest="120"
BackgroundColor="{StaticResource BackgroundColor}">
Style="{StaticResource SwipeItemBorderStyle}"/>
Style="{StaticResource SwipeItemIconStyle}">

FontFamily="{DynamicResource MaterialFontFamily}"
Glyph="{StaticResource Delete}"
Size="24"
Color="{StaticResource SwipeItemTextColor}" />


Text="Eliminar"
Style="{StaticResource SwipeItemTextStyle}"/>






Style="{StaticResource FrameStyle}">
VerticalOptions="Center"
RowSpacing="0" InputTransparent="True">








Grid.Column="0"
Grid.Row="0"
Text="{Binding Type}"
Style="{StaticResource CardDescriptionStyle}"
InputTransparent="True"/>
Grid.Column="0"
Grid.Row="1"
Text="{Binding Name}"
Style="{StaticResource CardHeader1Style}"
InputTransparent="True"/>

                            </Grid>
                        <Frame.GestureRecognizers>
                            <TapGestureRecognizer
                                Command="{Binding OnNavigateToVisitorsCommand}"
                                NumberOfTapsRequired="1"/>
                        </Frame.GestureRecognizers>    
                        </Frame>
                        <ScrollView
                            IsEnabled="False"
                            HorizontalOptions="End">
                            <Image
                                HeightRequest="80" Margin="0,0,0,0"
                                Aspect="AspectFit">
                                <Image.Source>
                                    <FontImageSource
                                                    FontFamily="{DynamicResource MaterialFontFamily}"
                                                    Glyph="{StaticResource HomeMapMarker}"
                                                    Size="80"
                                                    Color="{StaticResource YellowLightColor}" />
                                </Image.Source>
                            </Image>
                        </ScrollView>

                    </Grid>
                </SwipeView.Content>
            </SwipeView>
        </DataTemplate>
    </ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ScrollView Orientation="Vertical">
            <Grid HeightRequest="200" Margin = "8,0,8,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <CollectionView
                    x:Name="cvLocations"
                    Grid.Row="0"
                    ItemsSource="{Binding Locations}"
                    ItemTemplate="{StaticResource LocationTemplate}"
                    Margin="8, 0, 8, 110">
                    <CollectionView.ItemsLayout>
                        <LinearItemsLayout
                    Orientation="Vertical"
                    ItemSpacing="10"/>
                    </CollectionView.ItemsLayout>
                </CollectionView>
            </Grid>
        </ScrollView>
        <Button Grid.Row="0" Text="New"
                CornerRadius="12" BackgroundColor="{StaticResource AddButtonColor}"
                HorizontalOptions="FillAndExpand" HeightRequest="60"
                Margin="16,0,16,44" VerticalOptions="End"
                Style="{StaticResource ButtonStyle}" Command="{Binding OnNavigateToCreateCommand}"/>
    </Grid>
</ContentPage.Content>`

Instead of this

<Frame.GestureRecognizers>
                            <TapGestureRecognizer
                                Command="{Binding OnNavigateToVisitorsCommand}"
                                NumberOfTapsRequired="1"/>
</Frame.GestureRecognizers>    

you should have

<SwipeView.GestureRecognizers>
                            <TapGestureRecognizer
                                Command="{Binding OnNavigateToVisitorsCommand}"
                                NumberOfTapsRequired="1"/>
 </SwipeView.GestureRecognizers>    
<ContentPage.ToolbarItems>

<ToolbarItem.IconImageSource>

</ToolbarItem.IconImageSource>

</ContentPage.ToolbarItems>
<ContentPage.Resources>



<SwipeView.GestureRecognizers>
            <TapGestureRecognizer
                       Command="{Binding OnNavigateToVisitorsCommand}"
                       NumberOfTapsRequired="1"/>
             </Frame.GestureRecognizers>    
<SwipeView.RightItems>





<Image.Source>

</Image.Source>





</SwipeView.RightItems>
<SwipeView.Content>



<Grid.ColumnDefinitions>


</Grid.ColumnDefinitions>
<Grid.RowDefinitions>


</Grid.RowDefinitions>

                            </Grid>

                        </Frame>
                        <ScrollView
                            IsEnabled="False"
                            HorizontalOptions="End">
                            <Image
                                HeightRequest="80" Margin="0,0,0,0"
                                Aspect="AspectFit">
                                <Image.Source>
                                    <FontImageSource
                                                    FontFamily="{DynamicResource MaterialFontFamily}"
                                                    Glyph="{StaticResource HomeMapMarker}"
                                                    Size="80"
                                                    Color="{StaticResource YellowLightColor}" />
                                </Image.Source>
                            </Image>
                        </ScrollView>

                    </Grid>
                </SwipeView.Content>
            </SwipeView>
        </DataTemplate>
    </ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ScrollView Orientation="Vertical">
            <Grid HeightRequest="200" Margin = "8,0,8,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <CollectionView
                    x:Name="cvLocations"
                    Grid.Row="0"
                    ItemsSource="{Binding Locations}"
                    ItemTemplate="{StaticResource LocationTemplate}"
                    Margin="8, 0, 8, 110">
                    <CollectionView.ItemsLayout>
                        <LinearItemsLayout
                    Orientation="Vertical"
                    ItemSpacing="10"/>
                    </CollectionView.ItemsLayout>
                </CollectionView>
            </Grid>
        </ScrollView>
        <Button Grid.Row="0" Text="New"
                CornerRadius="12" BackgroundColor="{StaticResource AddButtonColor}"
                HorizontalOptions="FillAndExpand" HeightRequest="60"
                Margin="16,0,16,44" VerticalOptions="End"
                Style="{StaticResource ButtonStyle}" Command="{Binding OnNavigateToCreateCommand}"/>
    </Grid>
</ContentPage.Content>

I hope it works :)

@vhugogarcia

Hello @psp589 but I have it also there and it did not work. I have the gesture in 2 places: The frame and also the swipeview, let me change that and try right now

I just did it @psp589 and it did not work. This is my full code: https://gist.github.com/vhugogarcia/ccefb9c8cb76f143aa1e60d102adb030

Sorry I didn't realized before, but the difference between your code and mine is that you're biding the gesture to a command ( and I don't know why) that doesn't work. Try it like in my first example using tapped event instead of command
=>

  <SwipeView.GestureRecognizers>
                            <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1"/> 
          </SwipeView.GestureRecognizers>

xaml.cs =>

private void TapGestureRecognizer_Tapped_1(object sender, EventArgs e)
{
        // in my case I'm setting the selected item but you can execute a command or whatever you want from here
    MyCollectionView.SelectedItem = (sender as SwipeView).BindingContext;
}

@vhugogarcia

Actually, I was thinking the same yesterday and did a try by adding the Tapped event and it did not work. This issue should be something beyond that.

Any news on this bug?
The above solution where you put the TapGestureRecognizer on the SwipeView itself works great for when you only have 1 swipeItem. Problem is when you have more than 1 item, for example a "Edit" and Delete" swipeItem then this workaround obviously doesn't work.

In case that might help : #10305

I have experienced this issue today when SelectionChangedCommand of CollectionView not working with SwipeView

Was this page helpful?
0 / 5 - 0 ratings