maui-gestures

.NET MAUI Gesture Recognizers

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "maui-gestures" with this command: npx skills add davidortinau/maui-skills/davidortinau-maui-skills-maui-gestures

.NET MAUI Gesture Recognizers

All gesture recognizers inherit from GestureRecognizer and are added via View.GestureRecognizers .

<Image> <Image.GestureRecognizers> <TapGestureRecognizer Tapped="OnTapped" /> </Image.GestureRecognizers> </Image>

var tap = new TapGestureRecognizer(); tap.Tapped += OnTapped; image.GestureRecognizers.Add(tap);

Summary

Recognizer Key Properties Key Events / Commands Notes

TapGestureRecognizer

NumberOfTapsRequired , Buttons

Tapped , Command

Default 1 tap, primary button

SwipeGestureRecognizer

Direction , Threshold

Swiped , Command

Threshold default 100 DIU

PanGestureRecognizer

TouchPoints

PanUpdated

StatusType: Started/Running/Completed

PinchGestureRecognizer

— PinchUpdated

Scale, ScaleOrigin, Status

DragGestureRecognizer

CanDrag

DragStarting , DropCompleted

Auto data for Text/Image controls

DropGestureRecognizer

AllowDrop

DragOver , Drop

Platform-specific PlatformArgs

PointerGestureRecognizer

— PointerEntered/Exited/Moved/Pressed/Released

Matching commands; enables PointerOver visual state

TapGestureRecognizer

Property Type Default Description

NumberOfTapsRequired

int

1

Taps needed to fire

Buttons

ButtonsMask

Primary

Primary , Secondary , or both

Command

ICommand

— Fires on tap

CommandParameter

object

— Passed to Command

<Label Text="Tap me"> <Label.GestureRecognizers> <TapGestureRecognizer NumberOfTapsRequired="2" Buttons="Primary" Command="{Binding DoubleTapCommand}" /> </Label.GestureRecognizers> </Label>

var tap = new TapGestureRecognizer { NumberOfTapsRequired = 2, Buttons = ButtonsMask.Primary }; tap.Command = new Command(() => Debug.WriteLine("Double-tapped")); label.GestureRecognizers.Add(tap);

In .NET 10 ClickGestureRecognizer is deprecated. Use TapGestureRecognizer

(touch/stylus) and PointerGestureRecognizer (mouse hover/press) instead.

SwipeGestureRecognizer

Property Type Default Description

Direction

SwipeDirection

— Left , Right , Up , Down

Threshold

uint

100

Minimum distance in DIU

Command

ICommand

— Fires on swipe

SwipedEventArgs : Direction , Parameter .

<BoxView Color="Teal"> <BoxView.GestureRecognizers> <SwipeGestureRecognizer Direction="Left" Threshold="150" Swiped="OnSwiped" /> <SwipeGestureRecognizer Direction="Right" Swiped="OnSwiped" /> </BoxView.GestureRecognizers> </BoxView>

var swipe = new SwipeGestureRecognizer { Direction = SwipeDirection.Left, Threshold = 150 }; swipe.Swiped += (s, e) => Debug.WriteLine($"Swiped {e.Direction}"); boxView.GestureRecognizers.Add(swipe);

Add one recognizer per direction; a single recognizer handles only one.

PanGestureRecognizer

Property Type Default Description

TouchPoints

int

1

Number of fingers required

PanUpdatedEventArgs : StatusType (Started , Running , Completed ), TotalX , TotalY , GestureId .

<Image Source="photo.png"> <Image.GestureRecognizers> <PanGestureRecognizer PanUpdated="OnPanUpdated" /> </Image.GestureRecognizers> </Image>

var pan = new PanGestureRecognizer(); pan.PanUpdated += (s, e) => { if (e.StatusType == GestureStatus.Running) { image.TranslationX = e.TotalX; image.TranslationY = e.TotalY; } }; image.GestureRecognizers.Add(pan);

On iOS TotalX /TotalY are relative to the start; on Android they are relative to the previous event. Normalize in your handler if needed.

PinchGestureRecognizer

PinchGestureUpdatedEventArgs : Scale , ScaleOrigin (Point ), Status (Started , Running , Completed ).

<Image Source="photo.png"> <Image.GestureRecognizers> <PinchGestureRecognizer PinchUpdated="OnPinchUpdated" /> </Image.GestureRecognizers> </Image>

var pinch = new PinchGestureRecognizer(); pinch.PinchUpdated += (s, e) => { if (e.Status == GestureStatus.Running) image.Scale = Math.Clamp(image.Scale + (e.Scale - 1), 0.5, 3); }; image.GestureRecognizers.Add(pinch);

DragGestureRecognizer

Property Type Default Description

CanDrag

bool

true

Enables/disables dragging

Event Args Type Key Properties

DragStarting

DragStartingEventArgs

Data (DataPackage), Cancel

DropCompleted

DropCompletedEventArgs

DragDropResult

Label and Image auto-populate data packages. For custom data, set DragStartingEventArgs.Data .

<Label Text="Drag me" BackgroundColor="LightBlue"> <Label.GestureRecognizers> <DragGestureRecognizer CanDrag="True" DragStarting="OnDragStarting" /> </Label.GestureRecognizers> </Label>

var drag = new DragGestureRecognizer { CanDrag = true }; drag.DragStarting += (s, e) => { e.Data.Text = viewModel.ItemId; e.Data.Properties["payload"] = viewModel.SelectedItem; }; view.GestureRecognizers.Add(drag);

DropGestureRecognizer

Property Type Default Description

AllowDrop

bool

false

Must be true to receive drops

Event Args Type Key Properties

DragOver

DragEventArgs

AcceptedOperation , PlatformArgs

Drop

DropEventArgs

Data (DataPackageView), PlatformArgs

<StackLayout BackgroundColor="LightGray"> <StackLayout.GestureRecognizers> <DropGestureRecognizer AllowDrop="True" DragOver="OnDragOver" Drop="OnDrop" /> </StackLayout.GestureRecognizers> </StackLayout>

var drop = new DropGestureRecognizer { AllowDrop = true }; drop.Drop += async (s, e) => { var text = await e.Data.GetTextAsync(); }; target.GestureRecognizers.Add(drop);

PlatformArgs per platform:

Platform DragOver Drop

Android PlatformArgs.DragEvent

PlatformArgs.DragEvent

iOS / Mac Catalyst UIDropInteraction args UIDropInteraction args

Windows WinUI DragEventArgs

WinUI DragEventArgs

PointerGestureRecognizer

Event Command Property Fires When

PointerEntered

PointerEnteredCommand

Pointer enters view bounds

PointerExited

PointerExitedCommand

Pointer leaves view bounds

PointerMoved

PointerMovedCommand

Pointer moves within view

PointerPressed

PointerPressedCommand

Button pressed in view

PointerReleased

PointerReleasedCommand

Button released in view

PointerEventArgs.GetPosition(relativeTo) returns a Point? . Adding this recognizer enables the PointerOver VisualState .

<Border StrokeShape="RoundRectangle 8"> <Border.GestureRecognizers> <PointerGestureRecognizer PointerEnteredCommand="{Binding HoverInCommand}" PointerExitedCommand="{Binding HoverOutCommand}" PointerMoved="OnPointerMoved" /> </Border.GestureRecognizers> <VisualStateManager.VisualStateGroups> <VisualStateGroup Name="CommonStates"> <VisualState Name="PointerOver"> <VisualState.Setters> <Setter Property="BackgroundColor" Value="LightCyan" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Border>

var pointer = new PointerGestureRecognizer(); pointer.PointerMoved += (s, e) => Debug.WriteLine($"Pointer at {e.GetPosition(null)}"); border.GestureRecognizers.Add(pointer);

Best for mouse/stylus. On touch devices, pointer events fire but hover is not tracked.

Combining Multiple Gestures

Add multiple recognizers to the same collection. The platform resolves conflicts.

<Image Source="card.png"> <Image.GestureRecognizers> <TapGestureRecognizer Tapped="OnTapped" /> <PanGestureRecognizer PanUpdated="OnPan" /> <PinchGestureRecognizer PinchUpdated="OnPinch" /> <PointerGestureRecognizer PointerEntered="OnHover" /> </Image.GestureRecognizers> </Image>

Combining pan + swipe on the same view can conflict on Android. Test or use one at a time.

Platform Differences

Area iOS / Mac Catalyst Android Windows

Pan TotalX/TotalY Relative to start Relative to previous event Relative to start

Pointer hover Mouse/trackpad only Mouse only Mouse/pen

Cross-app drag-drop Supported (iPadOS/Mac) Not supported Supported

Secondary button tap Supported Long-press fallback Supported

Quick Rules

  • One SwipeGestureRecognizer per direction.

  • Use PointerGestureRecognizer for hover effects, not TapGestureRecognizer .

  • Set AllowDrop="True" on drop targets — it defaults to false .

  • Normalize pan deltas across platforms if sub-pixel accuracy matters.

  • Prefer commands over events for MVVM; both work identically.

  • In .NET 10 use TapGestureRecognizer instead of deprecated ClickGestureRecognizer .

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

maui-performance

No summary provided by upstream source.

Repository SourceNeeds Review
General

maui-data-binding

No summary provided by upstream source.

Repository SourceNeeds Review
General

maui-dependency-injection

No summary provided by upstream source.

Repository SourceNeeds Review
General

maui-permissions

No summary provided by upstream source.

Repository SourceNeeds Review