Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ButtonClickEventTriggerBehavior misses previously pressed modifiers #154

Open
JaggerJo opened this issue Mar 19, 2024 · 0 comments
Open

Comments

@JaggerJo
Copy link

I had 2 problems with ButtonClickEventTriggerBehavior.

  1. It seems that only modifier keys get tracked for events that reach the control:

    AssociatedObject.AddHandler(InputElement.KeyDownEvent, Button_OnKeyDown, RoutingStrategies.Tunnel);
    AssociatedObject.AddHandler(InputElement.KeyUpEvent, Button_OnKeyUp, RoutingStrategies.Tunnel);

  2. Key Events that happened outside of the control / before the control was created are not respected.

I might be wrong about 1.

My working modified version of ButtonClickEventTriggerBehavior is below, but I'm not really happy with the implementation as it involves setting event handlers on the top-level.

Is there a better way to archive this?

public static class ModifierKeyStateProvider
{
    public static KeyModifiers ModifierKeyState { get; set; }
}

public class ButtonClickModifierKeyBehavior : Trigger<Button>
{
    public static readonly StyledProperty<KeyModifiers> KeyModifiersProperty =
        AvaloniaProperty.Register<ButtonClickModifierKeyBehavior, KeyModifiers>(nameof(KeyModifiers));

    public KeyModifiers KeyModifiers
    {
        get => GetValue(KeyModifiersProperty);
        set => SetValue(KeyModifiersProperty, value);
    }

    protected override void OnAttachedToVisualTree()
    {
        if (AssociatedObject is not null)
        {
            AssociatedObject.Click += AssociatedObject_OnClick;
        }
    }

    protected override void OnDetachedFromVisualTree()
    {
        if (AssociatedObject is not null)
        {
            AssociatedObject.Click -= AssociatedObject_OnClick;
        }
    }

    private void AssociatedObject_OnClick(object? sender, RoutedEventArgs e)
    {
        if (AssociatedObject is not null && KeyModifiers == ModifierKeyStateProvider.ModifierKeyState)
        {
            Interaction.ExecuteActions(AssociatedObject, Actions, e);
        }
    }
}

Glue code in App code behind:

        var topLevel = this.GetTopLevel();

        topLevel.AddHandler(
            InputElement.KeyDownEvent,
            (s, e) => ModifierKeyStateProvider.ModifierKeyState = e.KeyModifiers,
            handledEventsToo: true
        );

        topLevel.AddHandler(
            InputElement.KeyUpEvent,
            (s, e) => ModifierKeyStateProvider.ModifierKeyState = e.KeyModifiers,
            handledEventsToo: true
        );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants