Skip to main content

Gesture events

GestureSimulator raises processed gesture events such as tapped, pinch, and scroll events directly. Use it to test gesture handlers. TouchInputSimulator raises targeted pointer events; use GestureRecognizerTestHelper when the recognizer itself is under test.

When to Use Which Simulator​

SimulatorUse Case
TouchInputSimulatorLow-level touch input testing, gesture recognizer testing
GestureSimulatorDirect gesture event testing, simulating processed gestures
GestureRecognizerTestHelperTesting gesture recognizer behavior with reflection

Basic Usage​

var simulator = new GestureSimulator();

// Simulate a tap gesture
simulator.Tap(control, new Point(100, 100));

// Simulate a double tap
simulator.DoubleTap(control, new Point(100, 100));

// Simulate a right tap (context menu)
simulator.RightTap(control, new Point(100, 100));

Tap Gestures​

// Standard tap with touch pointer
simulator.Tap(control, new Point(100, 100));

// Tap with specific pointer type
simulator.Tap(control, new Point(100, 100), PointerType.Mouse);
simulator.Tap(control, new Point(100, 100), PointerType.Pen);

// Tap with key modifiers (Ctrl, Shift, Alt)
simulator.Tap(control, new Point(100, 100), PointerType.Touch, KeyModifiers.Control);

// Double tap
simulator.DoubleTap(control, new Point(100, 100));

// Right tap (triggers context menu)
simulator.RightTap(control, new Point(100, 100));

Holding Gesture (Press and Hold)​

// Individual holding states
simulator.HoldingStarted(control, new Point(100, 100));
// ... simulate user holding for a duration ...
simulator.HoldingCompleted(control, new Point(100, 100));

// Or cancel the hold
simulator.HoldingCancelled(control, new Point(100, 100));

// Complete hold sequence (started + wait + completed)
simulator.Hold(control, new Point(100, 100), holdDuration: 500);

Pinch Gestures (Zoom/Rotate)​

// Single pinch event
simulator.Pinch(control, scale: 1.5, scaleOrigin: new Point(200, 150));

// Pinch with rotation
simulator.Pinch(control, scale: 1.5, scaleOrigin: new Point(200, 150), angleDelta: 0.1);

// End pinch gesture
simulator.PinchEnded(control);

// Complete pinch zoom sequence (multiple steps)
simulator.PinchZoom(
control,
origin: new Point(200, 150),
startScale: 1.0,
endScale: 2.0,
steps: 10
);

// Pinch rotation
simulator.PinchRotate(
control,
origin: new Point(200, 150),
startAngle: 0,
endAngle: 90, // degrees
steps: 10
);

Scroll Gestures​

// Single scroll event
var gestureId = simulator.GetNextGestureId();
simulator.Scroll(control, new Vector(0, 100), gestureId);
simulator.ScrollEnded(control, gestureId);

// Scroll with inertia (uses reflection for internal constructor)
simulator.ScrollInertiaStarting(control, gestureId, new Vector(0, 500));

// Complete scroll sequence
simulator.ScrollSequence(
control,
totalDelta: new Vector(0, 200),
steps: 10,
withInertia: false
);

// Scroll with inertia
simulator.ScrollSequence(
control,
totalDelta: new Vector(0, 200),
steps: 10,
withInertia: true,
inertiaVelocity: new Vector(0, 500)
);

Pull Gestures (Pull-to-Refresh)​

// Single pull event
var gestureId = simulator.GetNextGestureId();
simulator.Pull(control, new Vector(0, 50), PullDirection.TopToBottom, gestureId);
simulator.PullEnded(control, gestureId, PullDirection.TopToBottom);

// Complete pull-to-refresh sequence
simulator.PullToRefresh(
control,
direction: PullDirection.TopToBottom,
distance: 100,
steps: 10
);

Pull directions:

  • PullDirection.TopToBottom - Pull down to refresh
  • PullDirection.BottomToTop - Pull up
  • PullDirection.LeftToRight - Pull right
  • PullDirection.RightToLeft - Pull left

Touchpad Gestures (macOS Trackpad)​

// Touchpad magnify (pinch-to-zoom on trackpad)
simulator.TouchpadMagnify(control, new Vector(0.5, 0), new Point(200, 150));

// Touchpad rotate
simulator.TouchpadRotate(control, angleDelta: 45, position: new Point(200, 150));

// Touchpad swipe
simulator.TouchpadSwipe(control, new Vector(100, 0), new Point(200, 150));

// Complete magnify sequence
simulator.TouchpadMagnifySequence(
control,
position: new Point(200, 150),
totalMagnification: 1.0,
steps: 10
);

// Complete rotation sequence
simulator.TouchpadRotateSequence(
control,
position: new Point(200, 150),
totalAngle: 90, // degrees
steps: 10
);

// Swipe sequence
simulator.TouchpadSwipeSequence(
control,
position: new Point(200, 150),
direction: SwipeDirection.Left,
distance: 100,
steps: 10
);

Compound Gestures​

// Tap and hold (tap followed by hold)
simulator.TapAndHold(control, new Point(100, 100), holdDuration: 500);

// Double-tap-and-zoom (common iOS/Android pattern)
simulator.DoubleTapZoom(
control,
position: new Point(200, 150),
zoomScale: 2.0,
steps: 10
);

// Flick/fling (fast swipe with inertia)
simulator.Flick(
control,
direction: SwipeDirection.Up,
distance: 50,
velocity: 500
);

// Three-finger swipe (navigation)
simulator.ThreeFingerSwipe(
control,
position: new Point(200, 150),
direction: SwipeDirection.Left,
distance: 100
);

Time Management​

// Advance internal timestamp
simulator.AdvanceTime(milliseconds: 16);

// Get current timestamp
ulong currentTime = simulator.Timestamp;

// Reset simulator to initial state
simulator.Reset();

// Generate unique gesture IDs
int gestureId = simulator.GetNextGestureId();

Complete Example: Testing Pinch-to-Zoom​

[AvaloniaFact]
public void PinchZoom_ShouldScaleContent()
{
// Arrange
var zoomBorder = new Border { Width = 400, Height = 300 };
var content = new Border { Background = Brushes.Blue };
zoomBorder.Child = content;

var window = new Window { Content = zoomBorder };
window.Show();

var simulator = new GestureSimulator();
double? finalScale = null;

zoomBorder.AddHandler(Gestures.PinchEvent, (sender, args) =>
{
if (args is PinchEventArgs pinch)
{
finalScale = pinch.Scale;
}
});

// Act - Simulate pinch zoom from 1x to 2x
simulator.PinchZoom(zoomBorder, new Point(200, 150), 1.0, 2.0, steps: 5);

// Assert
Assert.NotNull(finalScale);
Assert.Equal(2.0, finalScale.Value, 2);
window.Close();
}