maui: .NET MAUI GestureRecognizers not working on certain controls
This issue has been moved from a ticket on Developer Community.
[severity:It’s more difficult to complete my work]
The following is working perfectly fine:
<Frame>
<Frame.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ExecuteCommand}" />
</Frame.GestureRecognizers>
</Frame>
While this is not working:
<CheckBox>
<CheckBox.GestureRecognizers >
<TapGestureRecognizer Command="{Binding ExecuteCommand}"/>
</CheckBox.GestureRecognizers>
</CheckBox>
The command is not executed.
The same goes for the Switch.
If this is intentional, what would be the proper way to bind a command to the Checkbox or Switch?
Original Comments
Feedback Bot on 7/17/2022, 08:01 PM:
(private comment, text removed)
Original Solutions
(no solutions)
Depends on
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 20
- Comments: 45 (8 by maintainers)
Commits related to this issue
- Gone as far as I can in the UI. Bloced by https://github.com/dotnet/maui/issues/8895 — committed to matt-goldman/dotnetflix by matt-goldman a year ago
Why is this issue not getting attention? This seems like a very basic feature that Maui needs to support. I keep on fighting with workarounds for Maui, it’s annoying.
Is there any idea when this is going to get looked at or resolved? This is a serious issue which blocks any iOS releases.
@davidortinau hi - sorry to bring you in the picture but we are all keen to port apps to maui but having gesture recognizers not working in collectionView - frames-etc. is a tough one to work around… Can you help?
Just to add to this issue. I’m seeing the same issue when using Tap Gesture’s inside of a Frame that is inside of a CollectionView.
XAML
csharp
I’m using the CommunityToolkit.MVVM, in case it’s important. I tried it without the top Grid and ScrollView and same results, the command is never called.
Edit:
I may just be an idiot. I changed:
to
And added
viewModelto my ContentPage like the below and it’s triggering now.Because unfortunately MAUI doesn’t have nearly enough resource assigned to it at Microsoft.
I use the tapgesturerecognizer nested in a collectionview and the command does not execute, if the item is not visible at loading time. So when i add many items to the bound observablecollection, the command is only executed for those items that are visible after that process.
Hi @imsam67 I call it on the entire page, in the code behind it looks like this:
this.InvalidateMeasure();I am then invoking this whenever the visibility of any of the content changes. Seems to do the trick even for elements which are nested within a ContentView then a StackLayout + Grid. Hope that this helps.I was finding an issue with content registering gestures if after a visibility change the view rendered it below the size of the screen (scroll down to view it). My workaround was to call InvalidateMeasure() on the view. Afterwards, all the gestures seem to be responding correctly. Hope this workaround solves some peoples problems in here.
This issue is an agglomeration of about half a dozen different issues, so I’m going to do my best to address them all.
First off - if you’ve seen issues on iOS where some tap gestures on a page fire and others further down do not, and your items are inside of a ScrollView: you might have been hitting a variation of #14257. It’s not a gesture issue, it’s a ScrollView issue. It’s been addressed in .NET 8, and it’s on the consideration list for backporting to .NET 7.
We’ve also addressed some issues on iOS in .NET 7 and 8 with layouts on iOS not having user interaction enabled; you may have run into these, and now they’re fixed. If you had problems with TapGestures on Grids, StackLayouts, ContentViews, Borders, Frames, etc., this may have been your actual issue.
We’ve fixed some problems with Frame on Android which may have been preventing TapGesture from firing reliably.
We’ve also addressed some interaction issues with Frames as parts of DataTemplates, so if you’ve had a problem with DataTemplates containing Frames not honoring your TapGestures, that’s likely been fixed.
If you’re having problems with gestures on Spans, we’re tracking that issue at https://github.com/dotnet/maui/issues/4734.
Because this issue has become so large and contains so many sub-issues unrelated to the original problem, we’re asking that anyone who is still experiencing problems with TapGesture on controls to open an issue specific to their situation so that we can address them appropriately. We will be closing this issue.
This code as a DataTemplate for CollectionView caused items to be invisible. Took some time to find the issue, which is very frustrating. I tried to change the event to command - items are now visible, but the command doesn’t fire. Tried switching Border to HorizontalStackLayout, but it has the same issue. I have no workaround. This definitely doesn’t get the attention it should be getting!
I have the same issue. As @Greg-Bates-Trimble said, when the visibility of control(s) (not necessarily the control that has the tap gesture) is changed, gesture stops working.
For now I stopped chaging the visibility of a control as a workaround, but this bug could be a real pain.
@Greg-Bates-Trimble Thank you! This workaround does work.
I’m also having this truly strange behavior in my .NET MAUI app targeting .NET 7 using the latest service release.
I use it with
Border’s and the weird thing is it works on oneBorderbut not the second one. It also worked a few times in the secondBorderthen it stopped. There’s no telling when it may work.I’m discouraged to see that this issue is also falling on deaf ears! It’s been open since July 22 and it’s still there.
Embedding the gesture in a CollectionView also doesn’t work.
But take the ContentView outside of the CollectionView and make it the only descendant of a page for example, then it works:
Edit: Nov/17/22: see the comment here
@otium99 yeah, the team needs to discuss this but we need to add a new api like CheckCommand to th checkbox … in the meanwhile you should use codebehind and subscribe the event and call your command from there.