Хотя основные ответы верны, мне лично нравится работать с прикрепленными свойствами, чтобы решение можно было применить к любому UIElement
, особенно когдаWindow
элемент не знает, какой элемент должен быть сфокусирован. По своему опыту я часто вижу композицию из нескольких моделей представления и пользовательских элементов управления, где окно часто является не чем иным, как корневым контейнером.
отрывок
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));
}
}
}
С помощью этого присоединенного свойства вы можете определить ярлык фокуса для любого UIElement. Он автоматически зарегистрирует входную привязку в окне, содержащем элемент.
Использование (XAML)
<TextBox x:Name="SearchTextBox"
Text={Binding Path=SearchText}
local:AttachedProperties.FocusShortcutKey="Ctrl+Q"/>
Исходный код
Полный пример, включая реализацию FocusElementCommand, доступен как суть: https://gist.github.com/shuebner20/c6a5191be23da549d5004ee56bcc352d
Отказ от ответственности: вы можете использовать этот код везде и бесплатно. Имейте в виду, что это образец, который не подходит для интенсивного использования. Например, отсутствует сборка мусора для удаленных элементов, потому что команда будет содержать сильную ссылку на элемент.