Aller au contenu

KeyBinding

De Banane Atomic

KeyBinding

Branchement de touches du clavier avec des Commands.
Le composant doit avoir le Keyboard Focus pour que les entrées clavier soient capturées.

TextBox

<TextBox Text="{Binding InputValue, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.InputBindings>
        <KeyBinding Key="Enter"
                    Command="{Binding ValidateCmd}" />
    </TextBox.InputBindings>
</TextBox>

Window

<Window.InputBindings>
    <KeyBinding Key="A" Command="{Binding Path=KeyCommand}"
                CommandParameter="A"/>
</Window.InputBindings>
public RelayCommand KeyCommand { get; set; }

KeyCommand = new RelayCommand(
    param =>
    {
        switch ((string)param)
        {
            case "A":
                Background = Brushes.AliceBlue;
                break;
            case "Z":
                Background = Brushes.AntiqueWhite;
                break;
        }
    });

Attention : Le Binding de type ElementName ne semble pas fonctionner avec KeyBinding.

Key Enum

Value Code Description
Back 2 Backspace
NumPad0 74 0
Decimal 88 . ,
Add 85 +
Return 6 Enter

Keyboard Focus

Behavior

FocusBehavior.cs
public sealed class FocusBehavior : Behavior<UserControl>
{
    protected override void OnAttached()
    {
        AssociatedObject.Focusable = true;
        AssociatedObject.Loaded += OnLoaded;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.Loaded -= OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        AssociatedObject.Focus();
    }
}
MyControl.xaml
<UserControl xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
             xmlns:behaviors="clr-namespace:MyApp.Behaviors">

    <b:Interaction.Behaviors>
        <behaviors:FocusBehavior />
    </b:Interaction.Behaviors>

Code behind

MyControl.xaml
<UserControl Focusable="True">
MyControl.xaml.cs
public MyControl()
{
    InitializeComponent();
    this.Loaded += (sender, args) => this.Focus();
}

Capture des touches pressées

// capture les touches pressées qui ne sont pas déjà capturées par des sous-controls.
KeyDown += new KeyEventHandler(MonControl_KeyDown);

// avec le paramètre handledEventsToo à true, capture toutes les touches pressées même celles qui sont pas déjà capturées par des sous-controls.
AddHandler(UIElement.PreviewKeyDownEvent, new KeyEventHandler(MonControl_PreviewKeyDown_EventHandled), true);

private void MonControl_PreviewKeyDown_EventHandled(object sender, KeyEventArgs e)
{
    // gestion des touches systèmes comme F10 qui affiche le menu
    // cette touche se trouve dans e.SystemKey au lieu de e.Key qui contient Key.System
    var key = e.Key == Key.System ? e.SystemKey : e.Key, e);
}

Convertion String → Key

Key myKey;
if (Enum.TryParse("Subtract", true, out myKey))
{ }

var keyConverter = new KeyConverter();
var myKey = keyConverter.ConvertFromString("Subtract");

Tester si la touche Ctrl est pressée

private bool IsCtrlKeyDown()
{
    return (Keyboard.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 || (Keyboard.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0;
}