Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -585,10 +585,13 @@ This section provides an overview of all available classes and their purpose in
- **HoldingTrigger**
*Triggers actions when a holding gesture is detected.*

- **KeyDownTrigger**
- **KeyDownTrigger**
*Listens for key down events and triggers actions if the pressed key (or gesture) matches the specified criteria.*

- **KeyUpTrigger**
- **KeyTrigger**
*Listens for key down or key up events and triggers actions when the configured key or gesture occurs.*

- **KeyUpTrigger**
*Listens for key up events and triggers actions when conditions are met.*

- **LostFocusTrigger**
Expand Down
3 changes: 3 additions & 0 deletions samples/BehaviorsTestApplication/Views/MainView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@
<TabItem Header="InteractionTriggerBehavior">
<pages:InteractionTriggerBehaviorView />
</TabItem>
<TabItem Header="KeyTrigger">
<pages:KeyTriggerView />
</TabItem>
<TabItem Header="Reactive Navigation">
<pages:ReactiveNavigationView />
</TabItem>
Expand Down
32 changes: 32 additions & 0 deletions samples/BehaviorsTestApplication/Views/Pages/KeyTriggerView.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<UserControl x:Class="BehaviorsTestApplication.Views.Pages.KeyTriggerView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:BehaviorsTestApplication.ViewModels"
x:DataType="vm:MainWindowViewModel"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="150">
<Design.DataContext>
<vm:MainWindowViewModel />
</Design.DataContext>
<StackPanel Margin="5">
<TextBlock Name="Message"
Text="Press Enter"
HorizontalAlignment="Center"
Margin="5" />
<TextBox Name="InputBox" Margin="5" Width="200">
<Interaction.Behaviors>
<KeyTrigger Key="Enter" Event="KeyDown">
<ChangePropertyAction TargetObject="Message"
PropertyName="Text"
Value="Enter Down" />
</KeyTrigger>
<KeyTrigger Key="Enter" Event="KeyUp">
<ChangePropertyAction TargetObject="Message"
PropertyName="Text"
Value="Enter Up" />
</KeyTrigger>
</Interaction.Behaviors>
</TextBox>
</StackPanel>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;

namespace BehaviorsTestApplication.Views.Pages;

public partial class KeyTriggerView : UserControl
{
public KeyTriggerView()
{
InitializeComponent();
}

private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using Avalonia.Input;
using Avalonia.Interactivity;

namespace Avalonia.Xaml.Interactions.Custom;

/// <summary>
/// A trigger that listens for key events and executes its actions when the
/// specified key or gesture is detected.
/// </summary>
public class KeyTrigger : RoutedEventTriggerBase<KeyEventArgs>
{
/// <summary>
/// Specifies which keyboard event will fire the trigger.
/// </summary>
public enum FiredOn
{
/// <summary>
/// Trigger on the <see cref="InputElement.KeyDownEvent"/>.
/// </summary>
KeyDown,

/// <summary>
/// Trigger on the <see cref="InputElement.KeyUpEvent"/>.
/// </summary>
KeyUp
}

/// <inheritdoc />
protected override RoutedEvent<KeyEventArgs> RoutedEvent
=> Event == FiredOn.KeyDown ? InputElement.KeyDownEvent : InputElement.KeyUpEvent;

/// <summary>
/// Identifies the <seealso cref="Key"/> avalonia property.
/// </summary>
public static readonly StyledProperty<Key?> KeyProperty =
AvaloniaProperty.Register<KeyTrigger, Key?>(nameof(Key));

/// <summary>
/// Identifies the <seealso cref="Gesture"/> avalonia property.
/// </summary>
public static readonly StyledProperty<KeyGesture?> GestureProperty =
AvaloniaProperty.Register<KeyTrigger, KeyGesture?>(nameof(Gesture));

/// <summary>
/// Identifies the <seealso cref="Event"/> avalonia property.
/// </summary>
public static readonly StyledProperty<FiredOn> EventProperty =
AvaloniaProperty.Register<KeyTrigger, FiredOn>(nameof(Event), FiredOn.KeyDown);

/// <summary>
/// Gets or sets the key to listen for. This is an avalonia property.
/// </summary>
public Key? Key
{
get => GetValue(KeyProperty);
set => SetValue(KeyProperty, value);
}

/// <summary>
/// Gets or sets the key gesture to match. This is an avalonia property.
/// </summary>
public KeyGesture? Gesture
{
get => GetValue(GestureProperty);
set => SetValue(GestureProperty, value);
}

/// <summary>
/// Gets or sets which key event fires the trigger. This is an avalonia property.
/// </summary>
public FiredOn Event
{
get => GetValue(EventProperty);
set => SetValue(EventProperty, value);
}

/// <inheritdoc />
protected override void Handler(object? sender, KeyEventArgs e)
{
if (!IsEnabled)
{
return;
}

var isKeySet = IsSet(KeyProperty);
var isGestureSet = IsSet(GestureProperty);
var key = Key;
var gesture = Gesture;
var haveKey = key is not null && isKeySet && e.Key == key;
var haveGesture = gesture is not null && isGestureSet && gesture.Matches(e);

if ((!isKeySet && !isGestureSet)
|| haveKey
|| haveGesture)
{
Execute(e);
}
}
}
Loading