WPF键绑定不起作用,因为Window无法集中注意力

时间:2014-08-28 11:37:51

标签: c# wpf xaml focus key-bindings

我有一个这样的窗口:

<Window Background="LightBlue" Title="SHMD Ämneshantering"
    x:Class="SHMD_Edit.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SHMD_Edit"
    xmlns:localViewModels="clr-namespace:SHMD_Edit.ViewModels"
    xmlns:localViews="clr-namespace:SHMD_Edit.Views"
     Height="700" Width="1105" MinHeight="750" MinWidth="1005" Focusable="True" Name="window">...</Window>

我尝试添加可在整个应用程序中使用的键绑定,如下所示:

<Window.InputBindings>
    <KeyBinding Gesture="CTRL+R" Command="{Binding AddSubstanceCommand}"/>
</Window.InputBindings>

然而,除非我把注意力放在像我的一个列表视图中的元素那样可聚焦的东西上,否则命令不会起作用。我希望用户能够在任何地方运行命令,所以我尝试将焦点添加到窗口,确定稍后聚焦的任何内容都将成为窗口的子项,因此手势应该传播到正确的目标。

然而,我无法专注于窗口,因为您看到我已将其设置为可聚焦,并且在立即窗口中检查时,我可以确认它确实是可聚焦的,但运行Focus()在它上面返回false并且没有设置焦点。

如何将焦点设置到窗口?获得全球可用的键绑定的任何其他方式?

1 个答案:

答案 0 :(得分:0)

之前我已经实现了全局快捷方式,我认为您缺少的是使用RoutedUICommands,它将通过可视树处理命令。如果你不这样做,你可能会遇到像你现在这样的奇怪聚焦问题。另一个关键点是使用正确的CommandManager注册方法,您要使用CommandManager.RegisterClassCommandBindingCommandManager.RegisterClassInputBinding,并将您的类型设置为Window,这显然会成为/// <summary> /// Defines the base class for application wide shortcuts. /// </summary> public abstract class ApplicationShortcut { /// <summary> /// The <see cref="ICommand"/> to be executed. /// </summary> public abstract ICommand Command { get; } /// <summary> /// The <see cref="InputGesture"/> defining how the <see cref="ApplicationShortcut.Command"/> is invoked. /// </summary> public abstract InputGesture Shortcut { get; } /// <summary> /// Registers the <see cref="ApplicationShortcut"/> with the application. /// </summary> public abstract void RegisterShortcut(); } /// <summary> /// Base class that defines an <see cref="ICommand"/> that is routed through the element tree and contains a text property. /// </summary> /// <typeparam name="T">The type that is registered with the command.</typeparam> public abstract class RoutedUIShortcut<T> : ApplicationShortcut { /// <summary> /// The type registered with the command. /// </summary> protected readonly Type OwnerType = typeof (T); /// <summary> /// The <see cref="RoutedUICommand"/> to be executed. /// </summary> protected abstract RoutedUICommand RoutedCommand { get; } /// <summary> /// The <see cref="ICommand"/> to be executed. /// </summary> public override sealed ICommand Command { get { return RoutedCommand; } } /// <summary> /// Registers the <see cref="ApplicationShortcut"/> with the application. /// </summary> public override void RegisterShortcut() { CommandManager.RegisterClassCommandBinding(OwnerType, new CommandBinding(Command, OnExecuted, OnCanExecute)); } /// <summary> /// Represents the method that will handle the <see cref="CommandBinding.CanExecute"/> routed event. /// </summary> /// <param name="sender">The command target that is invoking the handler.</param> /// <param name="e">The event data.</param> protected virtual void OnCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; } /// <summary> /// Represents the method that will handle the <see cref="CommandBinding.Executed"/> and <see cref="CommandBinding.PreviewExecuted"/> routed events, as well as related attached events. /// </summary> /// <param name="sender"></param> /// <param name="e">The event data.</param> protected abstract void OnExecuted(object sender, ExecutedRoutedEventArgs e); } 全球可用于WPF。

以下是我用于为应用程序创建快捷方式的两个抽象类。

RegisterShortcut()

然后,您只需在应用程序启动时实例化快捷方式类并调用{{1}}方法。