xamarin / XamarinCommunityToolkit

The Xamarin Community Toolkit is a collection of Animations, Behaviors, Converters, and Effects for mobile development with Xamarin.Forms. It simplifies and demonstrates common developer tasks building iOS, Android, and UWP apps with Xamarin.Forms.
MIT License
1.58k stars 471 forks source link

[Bug] NotSupportedException when removing element from a Grid using TouchEffect.Command #1659

Open robotjatek opened 3 years ago

robotjatek commented 3 years ago

Description

Removing models from an ObservableCollection in the viewmodel, crashes the application in some cases when using TouchEffect.Command. I can remove any random items from the collection except the very same which fired the delete command itself.

See GridPage.xaml in my Repository

ListView is working with both renderers.

Grid is working with buttons when using the legacy renderers, but crashes when using fast renderers. (See screenshot of the exception).

There are no problems with Grid&Button combo if I use the native Command and CommandParameter options. (Both renderers.)

BoxView crashes when used in grid with or without the UseLegacyRenderers flag when removed from the grid. But works fine in the listview with both renderers.

Button with xct Button with native commands BoxView Label
Grid fast renderer :x: :heavy_check_mark: :x: :x:
Grid legacy renderer :heavy_check_mark: :heavy_check_mark: :x: :heavy_check_mark:
ListView fast renderer :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:
ListView legacy renderer :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:

I tried to wrap my components inside a stack layout and binded my commands to the stacklayout itself, but its yielded the same result. Even an empty stacklayout crashes the app when used in grid with TouchEvents.

What curious is that I can remove any other random element from the ObservableCollection it wont crash the app up until that point where the firing element is removed from the grid. See RemoveLastCommand in the modelview or the GridRemoveLast tab in the app. I'm not even sure if this is a Xamarin or XCT bug or something is fundamentaly wrong in my implementation, but the fact that the button control acts differently with and without XCT tells me that it is an XCT bug. Apologies if I'm wrong.

xamarin_boxview_legacy xamarin_button_fast_renderer xamarin_stack_layout_fast

Stack Trace

Nothing in the stack trace window except for [External code].

Link to Reproduction Sample

Sample

Steps to Reproduce

  1. Use a grid with datatemplate and observable collection
  2. Bind a command to a control with xct:TouchEffect.Command
  3. Remove the firing element from the ObservableCollection with the binded command (removing any other elements from the collection works as expected)

Expected Behavior

Items get removed from the grid without NotSupportedExceptions

Actual Behavior

When the command is firing the application throws a NotSupportedException if the firing model get removed.

Basic Information

Workaround

In some cases using legacy renderers work, but not in all.

Reproduction imagery

bijington commented 2 years ago

I have had a quick look in to this. I haven't been able to work out where the faulting code exists however I have noticed that if the TouchEffect.Command approach in the GridRemoveLast.xaml is replaced with a TapGestureRecognizer on the Label then it behaves as expected. This alone makes me think there is something the toolkit is setting up which ultimately causes things to go wrong.

It is very strange that a new renderer is being created when the item is being removed.