【问题标题】:WPF Keybindings don't work since Window can't focus eventhough focusableWPF 键绑定不起作用,因为即使可聚焦,窗口也无法聚焦
【发布时间】:2014-08-28 11:37:50
【问题描述】:

我有一个这样的窗口:

<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并且没有设置焦点。

如何将焦点设置到我的窗口?还有其他方法可以获得全局可用的键绑定吗?

【问题讨论】:

  • 我制作了空窗口,RelayCommand 工作。您需要在此处放置标记以重现问题。无论如何,为什么不能在Window 中的任何位置放置任何元素(Visibility = Collapsed)并以编程方式对其调用 Focus() 方法?
  • 你在做一些事情,我没有将 datacontext 设置为整个窗口,而是设置为它包含的网格,这就是为什么没有按预期工作的原因。

标签: c# wpf xaml focus key-bindings


【解决方案1】:

我之前已经实现了全局快捷方式,我认为您缺少的部分是使用RoutedUICommands,它将处理通过可视树路由命令。如果你不这样做,你可能会遇到像现在这样奇怪的聚焦问题。另一个关键点是使用正确的CommandManager 注册方法,您想使用CommandManager.RegisterClassCommandBindingCommandManager.RegisterClassInputBinding 并将您的类型设置为Window,这显然会使其在全球范围内可用于WPF。

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

/// <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);
}

然后您只需要在应用程序启动时实例化您的 Shortcut 类并调用RegisterShortcut() 方法。

【讨论】:

  • 在哪里使用 InputGesture?
猜你喜欢
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多