CommunityToolkit / Maui

The .NET MAUI Community Toolkit is a community-created library that contains .NET MAUI Extensions, Advanced UI/UX Controls, and Behaviors to help make your life as a .NET MAUI developer easier
https://learn.microsoft.com/dotnet/communitytoolkit/maui
MIT License
2.07k stars 333 forks source link

[BUG] Wrong item is registered when pressing an item in a CollectionView using TouchBehavior #1865

Open TiicTac54 opened 1 week ago

TiicTac54 commented 1 week ago

Is there an existing issue for this?

Did you read the "Reporting a bug" section on Contributing file?

Current Behavior

When I press an item in a CollectionView using a TouchBehavior, another item is recorded as pressed.

https://github.com/CommunityToolkit/Maui/assets/56891833/5074828b-864d-4697-b6b3-a25ee0e307ae

Here's how I configure my TouchBehavior on each element of my list

 <CollectionView Grid.Row="1" ItemsSource="{Binding Items}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout ItemSpacing="4" Orientation="Vertical" />
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <VerticalStackLayout
                Padding="6"
                BackgroundColor="LightGray"
                HeightRequest="50">
                <Label Text="{Binding .}" />
                <VerticalStackLayout.Behaviors>
                    <toolkit:TouchBehavior Command="{Binding Source={x:Reference This},  Path=BindingContext.ItemTapCommandCommand}" CommandParameter="{Binding .}" />
                </VerticalStackLayout.Behaviors>
            </VerticalStackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Expected Behavior

If I press any item in the CollectionView, only the one I press should be registered.

Steps To Reproduce

  1. Have any list with enough items to be able to scroll.
  2. Scroll the list.
  3. Press any items

Link to public reproduction project repository

https://github.com/TiicTac54/TouchBehaviorBugWithCollectionView.git

Environment

- .NET MAUI CommunityToolkit:8.0.x
- OS:Android, iOS
- .NET MAUI:8.0.20

Anything else?

Using a TapGestureRecognizer does not cause this issue.

tranb3r commented 1 week ago

Isn't it a duplicate of #1804 ?

TiicTac54 commented 1 week ago

It could be, but for me regressing to 8.0.0 didn't work for me. I have the same issue whatever version I use

pictos commented 1 week ago

From what I can see the issue is the same as #1804.

@TiicTac54 can you test the nuget generated by this PR and tell me if that fixes your issue

holesnap commented 1 week ago

From what I can see the issue is the same as #1804.

@TiicTac54 can you test the nuget generated by this PR and tell me if that fixes your issue

how can I test the nuget generated by the PR? do you have the link?

TiicTac54 commented 1 week ago

@pictos I tried your fix and it works for android, but not for iOS. On iOS, the first press can be wrong, but if I do not scroll the second press will always be right. Adding ItemSizingStrategy="MeasureFirstItem" on the collectionView fixes the issue. However, that property with the TouchBehavior breaks on Android.

Finally, the issue (on iOS) only seems to occurs when navigating to a page from the collectionView, coming back and then press a new item. If I remove the navigation part, it works with no problem (fix and without the fix)

pictos commented 1 week ago

@TiicTac54 thanks for the info and try out, I'll see if I can address it on my current PR

maexsp commented 3 days ago

Run into same issue. When navigating into a sub page and navigate back than the registered item is wrong.

Hackmodford commented 2 days ago

This one bit me today

<CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="foot:DebugCommand">
                        <Grid>
                            <Border x:Name="AdvancedView"
                                    Margin="16,0"
                                    Style="{StaticResource AppGradientBorderNoOutline}">
                                <Border.Behaviors>
                                    <mct:TouchBehavior DefaultAnimationDuration="250"
                                                       Command="{Binding Command}"
                                                       DefaultAnimationEasing="{x:Static Easing.SpringOut}"
                                                       PressedScale=".95" />
                                </Border.Behaviors>
                                <Grid ColumnDefinitions="Auto, *" ColumnSpacing="16">
                                    <Label Grid.Column="0"
                                           Text="{StaticResource CircleDot}"
                                           TextColor="{Binding Command.IsRunning, Converter={StaticResource IsExecutingToColorConverter}}"
                                           FontSize="18"
                                           FontFamily="FontAwesome-Solid"
                                           VerticalOptions="Center" />
                                    <Label Grid.Column="1"
                                           Text="{Binding Title}"
                                           TextColor="{StaticResource TitleTextColor}"
                                           VerticalOptions="Center"
                                           FontSize="18" />
                                </Grid>
                            </Border>
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>

I'm literally binding the command to a command property in the datasource