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
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Windows.Input;
using ReactiveUI;

namespace BehaviorsTestApplication.ViewModels;

public partial class KeyGestureTriggerViewModel : ViewModelBase
{
public KeyGestureTriggerViewModel()
{
TriggerCommand = ReactiveCommand.Create(OnTriggered);
}

public ICommand TriggerCommand { get; }

private void OnTriggered()
{
Console.WriteLine("KeyGestureTrigger fired");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public partial class MainWindowViewModel : ViewModelBase
public MainWindowViewModel()
{
PointerTriggersViewModel = new PointerTriggersViewModel();
KeyGestureTriggerViewModel = new KeyGestureTriggerViewModel();

Count = 0;
Position = 100.0;
Expand Down Expand Up @@ -95,6 +96,9 @@ public MainWindowViewModel()
[Reactive]
public partial PointerTriggersViewModel PointerTriggersViewModel { get; set; }

[Reactive]
public partial KeyGestureTriggerViewModel KeyGestureTriggerViewModel { get; set; }

[Reactive]
public partial int Count { get; set; }

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 @@ -88,6 +88,9 @@
<TabItem Header="Pointer Triggers">
<pages:PointerTriggersView DataContext="{Binding PointerTriggersViewModel}" />
</TabItem>
<TabItem Header="KeyGestureTrigger">
<pages:KeyGestureTriggerView DataContext="{Binding KeyGestureTriggerViewModel}" />
</TabItem>
<TabItem Header="Storage Provider">
<pages:StorageProviderView />
</TabItem>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<UserControl x:Class="BehaviorsTestApplication.Views.Pages.KeyGestureTriggerView"
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:KeyGestureTriggerViewModel"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="150">
<Design.DataContext>
<vm:KeyGestureTriggerViewModel />
</Design.DataContext>

<Border Focusable="True" Padding="20" Background="LightGray">
<TextBlock Text="Press Ctrl+G" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Interaction.Behaviors>
<KeyGestureTrigger Gesture="Ctrl+G">
<InvokeCommandAction Command="{Binding TriggerCommand}" />
</KeyGestureTrigger>
</Interaction.Behaviors>
</Border>
</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 KeyGestureTriggerView : UserControl
{
public KeyGestureTriggerView()
{
InitializeComponent();
}

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

namespace Avalonia.Xaml.Interactions.Custom;

/// <summary>
/// Trigger that listens for a key gesture.
/// </summary>
public class KeyGestureTrigger : RoutedEventTriggerBase<KeyEventArgs>
{
/// <summary>
/// Identifies the <see cref="Gesture"/> avalonia property.
/// </summary>
public static readonly StyledProperty<KeyGesture?> GestureProperty =
AvaloniaProperty.Register<KeyGestureTrigger, KeyGesture?>(nameof(Gesture));

/// <summary>
/// Identifies the <see cref="FiredOn"/> avalonia property.
/// </summary>
public static readonly StyledProperty<KeyGestureTriggerFiredOn> FiredOnProperty =
AvaloniaProperty.Register<KeyGestureTrigger, KeyGestureTriggerFiredOn>(nameof(FiredOn),
defaultValue: KeyGestureTriggerFiredOn.KeyDown);

/// <summary>
/// Gets or sets the gesture that will fire the trigger.
/// </summary>
public KeyGesture? Gesture
{
get => GetValue(GestureProperty);
set => SetValue(GestureProperty, value);
}

/// <summary>
/// Gets or sets whether the trigger reacts on key down or key up.
/// </summary>
public KeyGestureTriggerFiredOn FiredOn
{
get => GetValue(FiredOnProperty);
set => SetValue(FiredOnProperty, value);
}

static KeyGestureTrigger()
{
EventRoutingStrategyProperty.OverrideMetadata<KeyGestureTrigger>(
new StyledPropertyMetadata<RoutingStrategies>(
defaultValue: RoutingStrategies.Tunnel | RoutingStrategies.Bubble));
}

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

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

var gesture = Gesture;
if (gesture is null || gesture.Matches(e))
{
Execute(e);
}
}
}

/// <summary>
/// Specifies when a <see cref="KeyGestureTrigger"/> should be fired.
/// </summary>
public enum KeyGestureTriggerFiredOn
{
/// <summary>
/// Trigger on key down.
/// </summary>
KeyDown,
/// <summary>
/// Trigger on key up.
/// </summary>
KeyUp
}
Loading