Obwohl die Top-Antworten korrekt sind, arbeite ich persönlich gerne mit angehängten Eigenschaften, damit die Lösung auf alle angewendet werden kann UIElement
, insbesondere wenn der Window
nicht weiß, auf welches Element fokussiert werden soll. Nach meiner Erfahrung sehe ich oft eine Komposition aus mehreren Ansichtsmodellen und Benutzersteuerelementen, wobei das Fenster oft nichts anderes als der Stammcontainer ist.
Snippet
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));
}
}
}
Mit dieser angehängten Eigenschaft können Sie eine Fokusverknüpfung für jedes UIElement definieren. Die Eingabebindung wird automatisch in dem Fenster registriert, das das Element enthält.
Verwendung (XAML)
<TextBox x:Name="SearchTextBox"
Text={Binding Path=SearchText}
local:AttachedProperties.FocusShortcutKey="Ctrl+Q"/>
Quellcode
Das vollständige Beispiel einschließlich der Implementierung von FocusElementCommand ist als Inhalt verfügbar: https://gist.github.com/shuebner20/c6a5191be23da549d5004ee56bcc352d
Haftungsausschluss: Sie können diesen Code überall und kostenlos verwenden. Bitte beachten Sie, dass dies ein Muster ist, das nicht für starke Beanspruchung geeignet ist. Beispielsweise gibt es keine Speicherbereinigung für entfernte Elemente, da der Befehl einen starken Verweis auf das Element enthält.