Install
$ agentstack add skill-linuxdevel-avalonia-skills-avalonia-input-interaction ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Avalonia Input & Interaction
Overview
All input routes as routed events (bubbling by default, tunneling with "Preview" prefix). Pointer events are unified across mouse, touch, and stylus.
Pointer Events
| Event | Fires when | |---|---| | PointerPressed | Button/finger down | | PointerReleased | Button/finger up | | PointerMoved | Pointer moves over control | | PointerEntered | Pointer enters bounds | | PointerExited | Pointer leaves bounds | | PointerCaptureLost | Capture released | | Tapped | Quick tap/click | | DoubleTapped | Double tap/click | | RightTapped | Right-click / long press |
myControl.PointerPressed += (s, e) =>
{
var point = e.GetPosition(myControl);
var props = e.GetCurrentPoint(myControl).Properties;
if (props.IsLeftButtonPressed) { /* left click */ }
if (props.IsRightButtonPressed) { /* right click */ }
if (props.IsMiddleButtonPressed) { /* middle click */ }
};
Capture pointer (receive events outside bounds):
myControl.PointerPressed += (s, e) =>
{
e.Pointer.Capture(myControl);
};
myControl.PointerReleased += (s, e) =>
{
e.Pointer.Capture(null); // release
};
Check pointer type:
myControl.PointerPressed += (s, e) =>
{
if (e.Pointer.Type == PointerType.Touch) { /* touch */ }
if (e.Pointer.Type == PointerType.Pen) { /* stylus */ }
};
Keyboard Events
| Event | Fires when | |---|---| | KeyDown | Key pressed (repeats while held) | | KeyUp | Key released | | TextInput | Text character produced |
myControl.KeyDown += (s, e) =>
{
if (e.Key == Key.Enter && e.KeyModifiers == KeyModifiers.Control)
{
e.Handled = true; // stop bubbling + prevent default
SubmitForm();
}
};
myTextBox.TextInput += (s, e) =>
{
if (!char.IsDigit(e.Text![0]))
e.Handled = true; // block non-digit input
};
KeyModifiers flags: None, Alt, Control, Shift, Meta (combinable with |)
// Ctrl+Shift+Z
if (e.Key == Key.Z && e.KeyModifiers == (KeyModifiers.Control | KeyModifiers.Shift))
Hot Keys
XAML registration:
Code registration:
HotKeyManager.RegisterHotKey(myControl, new KeyGesture(Key.S, KeyModifiers.Control));
HotKeyManager.SetHotKey(myButton, new KeyGesture(Key.F5));
Unregister:
HotKeyManager.SetHotKey(myControl, null);
Focus
// Programmatic focus
myControl.Focus();
// Via FocusManager
var fm = TopLevel.GetTopLevel(this)?.FocusManager;
fm?.Focus(myControl, NavigationMethod.Tab);
// Get currently focused element
var focused = fm?.GetFocusedElement();
XAML focus control:
Pseudoclasses for styling:
Focus scope (contains Tab navigation):
Gesture Recognizers
Add to any InputElement.GestureRecognizers:
private void OnPinchUpdated(object? sender, PinchEventArgs e)
{
_scale *= e.Scale;
myBorder.RenderTransform = new ScaleTransform(_scale, _scale);
}
| Recognizer | Events | |---|---| | TapGestureRecognizer | Tapped | | DoubleTapGestureRecognizer | DoubleTapped | | PinchGestureRecognizer | PinchUpdated, PinchEnded | | PullGestureRecognizer | PullDelta, PullEnded | | ScrollGestureRecognizer | ScrollGesture, ScrollGestureEnded, ScrollGestureInertiaStarting |
Drag and Drop
Source (initiates drag):
private async void OnPointerPressed(object? sender, PointerPressedEventArgs e)
{
var data = new DataObject();
data.Set(DataFormats.Text, "dragged text");
data.Set("custom/format", myObject);
var result = await DragDrop.DoDragDrop(e, data,
DragDropEffects.Copy | DragDropEffects.Move);
// result: DragDropEffects indicating what happened
}
Target (receives drop):
private void OnDragOver(object? sender, DragEventArgs e)
{
e.DragEffects = e.Data.Contains(DataFormats.Text)
? DragDropEffects.Copy
: DragDropEffects.None;
e.Handled = true;
}
private void OnDrop(object? sender, DragEventArgs e)
{
if (e.Data.Contains(DataFormats.Text))
{
var text = e.Data.GetText();
// use text
}
if (e.Data.Contains(DataFormats.Files))
{
var files = e.Data.GetFiles();
// IEnumerable
}
}
Built-in DataFormats: Text, Files, FileNames
Cursor
Available cursors: Default, Arrow, Cross, Hand, Help, IBeam, No, SizeAll, SizeNESW, SizeNS, SizeNWSE, SizeWE, TopSide, BottomSide, LeftSide, RightSide, Wait, None
Custom cursor from bitmap:
var cursor = new Cursor(myBitmap, new PixelPoint(hotspotX, hotspotY));
myControl.Cursor = cursor;
Scroll Events
myControl.PointerWheelChanged += (s, e) =>
{
var delta = e.Delta; // Vector: X for horizontal, Y for vertical
ScrollBy(-delta.Y * 30);
};
Common Mistakes
- Not setting
e.Handled = trueonKeyDown— event bubbles to parent;TextBoxwill still consume keys DragDrop.DoDragDropmust be called on pointer event — calling afterawaitloses the pointer event contextFocus()before control is attached to visual tree — silently does nothing; call inOnAttachedToVisualTreeor later- Gesture recognizers vs. events —
Tapped/DoubleTappedfire onInputElementdirectly;TapGestureRecognizerneeded only for custom gesture behavior DragDrop.AllowDropis an attached property — must be set on the drop target, not a parentPointerPressedfires beforeTapped— don't handle both if one is sufficient
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: linuxdevel
- Source: linuxdevel/Avalonia-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.