แม้ว่าคำตอบด้านบนจะถูกต้อง แต่โดยส่วนตัวแล้วฉันชอบทำงานกับคุณสมบัติที่แนบมาเพื่อให้สามารถนำโซลูชันไปใช้กับข้อใดก็ได้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
ข้อจำกัดความรับผิดชอบ: คุณสามารถใช้รหัสนี้ได้ทุกที่และไม่มีค่าใช้จ่าย โปรดทราบว่านี่เป็นตัวอย่างที่ไม่เหมาะสำหรับการใช้งานหนัก ตัวอย่างเช่นไม่มีการรวบรวมขยะขององค์ประกอบที่ถูกลบเนื่องจากคำสั่งจะมีการอ้างอิงถึงองค์ประกอบที่ชัดเจน