Skip to main content
Avalonia provides a unified pointer event system that handles mouse input along with other pointer types (touch, pen). The mouse device processes raw pointer events and dispatches them to controls.

PointerEventArgs

Base class for pointer-related events, including mouse events.

Properties

Pointer
IPointer
Gets the specific pointer generated by the input device. Each mouse, touch contact, or pen has its own pointer ID.
Timestamp
ulong
Gets the time when the input occurred, in milliseconds.
KeyModifiers
KeyModifiers
Gets a value that indicates which key modifiers (Ctrl, Shift, Alt) were active when the pointer event was initiated.
Properties
PointerPointProperties
Gets the state of the pointer device when this event occurred, including which buttons are pressed.

Methods

GetPosition
Point
Gets the pointer position relative to a control.
Point position = e.GetPosition(myControl);
Pass null to get the position in toplevel coordinates.
GetCurrentPoint
PointerPoint
Returns the PointerPoint associated with the current event, relative to the specified visual.
PointerPoint point = e.GetCurrentPoint(this);
GetIntermediatePoints
IReadOnlyList<PointerPoint>
Returns intermediate pointer points that occurred between the last event and this one. Useful for smooth drawing or gesture recognition.
var points = e.GetIntermediatePoints(canvas);
foreach (var point in points)
{
    DrawPoint(point.Position);
}
PreventGestureRecognition
void
Prevents this event from being handled by gesture recognizers in the route.
e.PreventGestureRecognition();

PointerPressedEventArgs

Provides information for pointer pressed (mouse down) events.

Properties

ClickCount
int
Gets the number of clicks (1 for single click, 2 for double click, etc.).

PointerReleasedEventArgs

Provides information for pointer released (mouse up) events.

Properties

InitialPressMouseButton
MouseButton
Gets the mouse button that triggered the corresponding PointerPressed event.

PointerWheelEventArgs

Provides information for mouse wheel events.

Properties

Delta
Vector
Gets the mouse wheel delta.
  • Delta.Y represents vertical scrolling (positive = scroll up, negative = scroll down)
  • Delta.X represents horizontal scrolling (if supported)

MouseButton Enumeration

Defines mouse buttons:
  • None - No button
  • Left - Left mouse button
  • Right - Right mouse button
  • Middle - Middle mouse button (wheel click)
  • XButton1 - First extended button
  • XButton2 - Second extended button

PointerPointProperties

Describes the state of a pointer device.

Properties

  • IsLeftButtonPressed - Gets whether the left button is pressed
  • IsRightButtonPressed - Gets whether the right button is pressed
  • IsMiddleButtonPressed - Gets whether the middle button is pressed
  • IsXButton1Pressed - Gets whether the first extended button is pressed
  • IsXButton2Pressed - Gets whether the second extended button is pressed
  • PointerUpdateKind - Gets the type of pointer update (left/right/middle button down/up, etc.)

Usage Examples

Handling Mouse Click Events

public class MyControl : Control
{
    protected override void OnPointerPressed(PointerPressedEventArgs e)
    {
        var point = e.GetCurrentPoint(this);
        
        if (point.Properties.IsLeftButtonPressed)
        {
            // Handle left click
            if (e.ClickCount == 2)
            {
                // Double click
                OnDoubleClick();
            }
            else
            {
                // Single click
                OnSingleClick();
            }
            e.Handled = true;
        }
        else if (point.Properties.IsRightButtonPressed)
        {
            // Show context menu
            ShowContextMenu(e.GetPosition(this));
            e.Handled = true;
        }
        
        base.OnPointerPressed(e);
    }
}

Tracking Mouse Movement

private bool _isDragging;
private Point _startPoint;

protected override void OnPointerPressed(PointerPressedEventArgs e)
{
    var point = e.GetCurrentPoint(this);
    if (point.Properties.IsLeftButtonPressed)
    {
        _isDragging = true;
        _startPoint = e.GetPosition(this);
        e.Pointer.Capture(this);
        e.Handled = true;
    }
}

protected override void OnPointerMoved(PointerEventArgs e)
{
    if (_isDragging)
    {
        var currentPoint = e.GetPosition(this);
        var delta = currentPoint - _startPoint;
        
        // Update position or perform drag operation
        UpdateDragPosition(delta);
        e.Handled = true;
    }
}

protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
    if (_isDragging)
    {
        _isDragging = false;
        e.Pointer.Capture(null);
        e.Handled = true;
    }
}

Handling Mouse Wheel

protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
{
    // Zoom with Ctrl + Wheel
    if (e.KeyModifiers.HasFlag(KeyModifiers.Control))
    {
        var zoomDelta = e.Delta.Y;
        if (zoomDelta > 0)
        {
            ZoomIn();
        }
        else if (zoomDelta < 0)
        {
            ZoomOut();
        }
        e.Handled = true;
    }
    else
    {
        // Normal scrolling
        Scroll(e.Delta.Y * ScrollSpeed);
    }
    
    base.OnPointerWheelChanged(e);
}

Drawing with Mouse

private readonly List<Point> _points = new();

protected override void OnPointerPressed(PointerPressedEventArgs e)
{
    var point = e.GetCurrentPoint(this);
    if (point.Properties.IsLeftButtonPressed)
    {
        _points.Clear();
        _points.Add(e.GetPosition(this));
        e.Pointer.Capture(this);
    }
}

protected override void OnPointerMoved(PointerEventArgs e)
{
    if (e.Pointer.Captured == this)
    {
        // Get all intermediate points for smooth drawing
        var intermediatePoints = e.GetIntermediatePoints(this);
        foreach (var point in intermediatePoints)
        {
            _points.Add(point.Position);
        }
        InvalidateVisual();
    }
}

public override void Render(DrawingContext context)
{
    if (_points.Count > 1)
    {
        var pen = new Pen(Brushes.Black, 2);
        for (int i = 0; i < _points.Count - 1; i++)
        {
            context.DrawLine(pen, _points[i], _points[i + 1]);
        }
    }
}

Checking Modifier Keys

protected override void OnPointerPressed(PointerPressedEventArgs e)
{
    var point = e.GetCurrentPoint(this);
    
    if (point.Properties.IsLeftButtonPressed)
    {
        if (e.KeyModifiers.HasFlag(KeyModifiers.Control))
        {
            // Ctrl+Click: Add to selection
            AddToSelection();
        }
        else if (e.KeyModifiers.HasFlag(KeyModifiers.Shift))
        {
            // Shift+Click: Extend selection
            ExtendSelection();
        }
        else
        {
            // Normal click: Replace selection
            ReplaceSelection();
        }
    }
}

Best Practices

  1. Use Pointer Events: Prefer PointerPressed, PointerMoved, PointerReleased over legacy mouse events for better cross-platform support
  2. Capture the Pointer: Use e.Pointer.Capture(this) during drag operations to ensure you receive all events
  3. Release Capture: Always release capture with e.Pointer.Capture(null) when done
  4. Mark Events as Handled: Set e.Handled = true to prevent event bubbling
  5. Check PointerType: Use e.Pointer.Type to distinguish between mouse, touch, and pen input
  6. Use Intermediate Points: For drawing or gesture recognition, use GetIntermediatePoints() to avoid missing events

Build docs developers (and LLMs) love