Bien que les principales réponses soient correctes, j'aime personnellement travailler avec les propriétés attachées pour permettre à la solution d'être appliquée à tout UIElement
, en particulier lorsque le Window
n'est pas conscient de l'élément qui doit être ciblé. D'après mon expérience, je vois souvent une composition de plusieurs modèles de vue et de contrôles utilisateur, où la fenêtre n'est souvent rien de plus que le conteneur racine.
Fragment
public sealed class AttachedProperties
{
// Define the key gesture type converter
[System.ComponentModel.TypeConverter(typeof(System.Windows.Input.KeyGestureConverter))]
public static KeyGesture GetFocusShortcut(DependencyObject dependencyObject)
{
return (KeyGesture)dependencyObject?.GetValue(FocusShortcutProperty);
}
public static void SetFocusShortcut(DependencyObject dependencyObject, KeyGesture value)
{
dependencyObject?.SetValue(FocusShortcutProperty, value);
}
/// <summary>
/// Enables window-wide focus shortcut for an <see cref="UIElement"/>.
/// </summary>
// Using a DependencyProperty as the backing store for FocusShortcut. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FocusShortcutProperty =
DependencyProperty.RegisterAttached("FocusShortcut", typeof(KeyGesture), typeof(AttachedProperties), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(OnFocusShortcutChanged)));
private static void OnFocusShortcutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is UIElement element) || e.NewValue == e.OldValue)
return;
var window = FindParentWindow(d);
if (window == null)
return;
var gesture = GetFocusShortcut(d);
if (gesture == null)
{
// Remove previous added input binding.
for (int i = 0; i < window.InputBindings.Count; i++)
{
if (window.InputBindings[i].Gesture == e.OldValue && window.InputBindings[i].Command is FocusElementCommand)
window.InputBindings.RemoveAt(i--);
}
}
else
{
// Add new input binding with the dedicated FocusElementCommand.
// see: https://gist.github.com/shuebner20/349d044ed5236a7f2568cb17f3ed713d
var command = new FocusElementCommand(element);
window.InputBindings.Add(new InputBinding(command, gesture));
}
}
}
Avec cette propriété jointe, vous pouvez définir un raccourci de focus pour n'importe quel UIElement. Il enregistrera automatiquement la liaison d'entrée dans la fenêtre contenant l'élément.
Utilisation (XAML)
<TextBox x:Name="SearchTextBox"
Text={Binding Path=SearchText}
local:AttachedProperties.FocusShortcutKey="Ctrl+Q"/>
Code source
L'exemple complet, y compris l'implémentation de FocusElementCommand, est disponible sous forme de fichier essentiel: https://gist.github.com/shuebner20/c6a5191be23da549d5004ee56bcc352d
Avertissement: Vous pouvez utiliser ce code partout et gratuitement. Veuillez garder à l'esprit qu'il s'agit d'un échantillon qui ne convient pas à un usage intensif. Par exemple, il n'y a pas de garbage collection des éléments supprimés car la commande contiendra une référence forte à l'élément.