5

I need both long-press and short-press in a list

I am using effects for long-press for items in a list (ListView/CollectionView) but when that works the short-press (tap) doesn't!

My question is: Do I need to create another effects version that is short-click or can I somehow have both? I have searched everywhere without any information to help me discover a solution...

I have been playing around with this code in my repository with out being able to make both work at the same time.

<CollectionView
  x:Name="carsCollection"
  ItemsSource="{Binding Cars}"
  SelectionMode="Single"
  SelectionChangedCommand="{Binding TapCommand}"
  SelectionChangedCommandParameter="{Binding Source={x:Reference carsCollection}, Path=SelectedItem}"
  BackgroundColor="Orange">
  <CollectionView.ItemTemplate>
    <DataTemplate>
      <ContentView>
        <StackLayout
          effects:LongPressedEffect.Command="{Binding Path=BindingContext.LongTapCommand, Source={x:Reference ThisPage}}"
          effects:LongPressedEffect.CommandParameter="{Binding .}">
          <Label Text="CollectionView: Long Press works but not normal selection" />
          <StackLayout.Effects>
            <effects:LongPressedEffect />
          </StackLayout.Effects>
        </StackLayout>
      </ContentView>
    </DataTemplate>
  </CollectionView.ItemTemplate>
</CollectionView>

The ViewModel containing the commands is here.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Sturla
  • 3,446
  • 3
  • 39
  • 56

3 Answers3

7

You can use TouchEffect highly customizable from Xamarin Community Toolkit package (which is a package that gathers a lot of cool reusable/common controls, effects, behaviors...).

Sample of usage where you can even control the duration of the long press (default = 500ms):

 xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
<StackLayout
xct:TouchEffect.LongPressCommand="{Binding Path=BindingContext.LongTapCommand, Source={x:Reference ThisPage}}"
xct:TouchEffect.LongPressCommandParameter="{Binding .}"
xct:TouchEffect.LongPressDuration="2000"
xct:TouchEffect.Command="{Binding Path=BindingContext.TapCommand, Source={x:Reference ThisPage}}"
xct:TouchEffect.CommandParameter="{Binding .}">

Also, you can apply animation and lot of other stuff.

Resource

Documentation (under work) https://learn.microsoft.com/en-us/xamarin/community-toolkit/

Repo https://github.com/xamarin/XamarinCommunityToolkit/

https://www.youtube.com/watch?v=BcFlZMhPmVk

Cfun
  • 8,442
  • 4
  • 30
  • 62
  • 3
    For anyone using this: You can't combine a longpress with a regular gesture recognizer. Having them both requires using the toolkit for both – Gertjan Brouwer May 23 '21 at 19:07
0

My question is: Do I need to create another effects version that is short-click or can I somehow have both? I have searched everywhere without any information to help me discover a solution...

You could do that with control which has click event instead of stacklayout.

Make the long press follow the stpes in the link below. And then use click event to perform shot press. How to make long press gesture in Xamarin Forms?

Or you could use the tap gesture recognizer. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/gestures/tap

Wendy Zang - MSFT
  • 10,509
  • 1
  • 7
  • 17
0

Using an effect on a ImageButton worked in my case:

                    <CollectionView.ItemTemplate>
                        <DataTemplate x:DataType="sharedmodels:Photo">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <ImageButton Source="{Binding ThumbnailUrl, Converter={StaticResource ImageLocalStorageUrlConverter}}"
                                             Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.SelectCommand}" 
                                             CommandParameter="{Binding .}"
                                             effects:LongPressEffect.Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.DeleteCommand}"
                                             effects:LongPressEffect.CommandParameter="{Binding .}">
                                    <ImageButton.Effects>
                                        <effects:LongPressEffect/>
                                    </ImageButton.Effects>
                                </ImageButton>
                            </Grid>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
unsane
  • 81
  • 1
  • 6