如何在 WPF 中读取用户的自定义键盘快捷键?

发布于 2024-08-19 15:50:20 字数 1193 浏览 6 评论 0原文

在我的应用程序中,我想让用户自定义键盘快捷键,就像在 Visual Studio 的键盘选项中所做的那样。用户可以聚焦空白文本框,然后键入他想要分配给命令的任何快捷方式。

我最接近的方法是订阅 TextBox.PreviewKeyDown 事件,将其设置为已处理,以防止在文本框中实际输入文本。然后,我忽略与修饰键关联的 KeyDown 事件(是否有更清晰的方法来确定某个键是否为修饰键?)。

// Code-behind
private void ShortcutTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    // The text box grabs all input
    e.Handled = true;

    if (e.Key == Key.LeftCtrl || 
        e.Key == Key.RightCtrl || 
        e.Key == Key.LeftAlt ||
        e.Key == Key.RightAlt || 
        e.Key == Key.LeftShift ||
        e.Key == Key.RightShift)
        return;

    string shortcutText = "";
    if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
        shortcutText += "Ctrl+";
    if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
        shortcutText += "Shift+";
    if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
        shortcutText += "Alt+";
    _ShortcutTextBox.Text = shortcutText + e.Key.ToString();

}

以上适用于任何以 Ctrl 和 Ctrl+Shift 开头的快捷方式,但不适用于任何 Alt 快捷方式。当我按下包含 Alt 的快捷键时,e.Key 始终设置为 Key.System

如何记录用户的 Alt 快捷键?有没有更好、更稳健的方法来记录用户的快捷方式?

In my application, I want to let users customize keyboard shortcuts, just like it's done in Visual Studio's keyboard options. The user can focus a blank text box and then type any shortcut he wants to assign to a command.

The closest I've come to make it work is by subscribing to the TextBox.PreviewKeyDown event, setting it as handled to prevent actual text input in the text box. I then ignore the KeyDown events associated with modifier keys (is there a cleaner way to determine if a Key is a modifier key?).

// Code-behind
private void ShortcutTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    // The text box grabs all input
    e.Handled = true;

    if (e.Key == Key.LeftCtrl || 
        e.Key == Key.RightCtrl || 
        e.Key == Key.LeftAlt ||
        e.Key == Key.RightAlt || 
        e.Key == Key.LeftShift ||
        e.Key == Key.RightShift)
        return;

    string shortcutText = "";
    if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
        shortcutText += "Ctrl+";
    if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
        shortcutText += "Shift+";
    if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
        shortcutText += "Alt+";
    _ShortcutTextBox.Text = shortcutText + e.Key.ToString();

}

The above works for any shortcut starting with Ctrl and Ctrl+Shift, but fails for any Alt shortcuts. The e.Key is always set to Key.System when I press a shortcut containing Alt.

How can I record Alt shortcuts from the user? Is there a better, more robust way to record shortcuts form the user?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我是有多爱你 2024-08-26 15:50:20

诀窍是使用 SystemKey属性(如果设置了 Key 属性) to Key.System

private void ShortcutTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    // The text box grabs all input.
    e.Handled = true;

    // Fetch the actual shortcut key.
    Key key = (e.Key == Key.System ? e.SystemKey : e.Key);

    // Ignore modifier keys.
    if (key == Key.LeftShift || key == Key.RightShift
        || key == Key.LeftCtrl || key == Key.RightCtrl
        || key == Key.LeftAlt || key == Key.RightAlt
        || key == Key.LWin || key == Key.RWin) {
        return;
    }

    // Build the shortcut key name.
    StringBuilder shortcutText = new StringBuilder();
    if ((Keyboard.Modifiers & ModifierKeys.Control) != 0) {
        shortcutText.Append("Ctrl+");
    }
    if ((Keyboard.Modifiers & ModifierKeys.Shift) != 0) {
        shortcutText.Append("Shift+");
    }
    if ((Keyboard.Modifiers & ModifierKeys.Alt) != 0) {
        shortcutText.Append("Alt+");
    }
    shortcutText.Append(key.ToString());

    // Update the text box.
    _ShortcutTextBox.Text = shortcutText.ToString();
}

我将左右Windows键添加到修饰符列表中,因为它们有时会在复杂时出现在快捷键名称中(Ctrl+ Shift+Alt)组合键是从终端服务器会话中键入的。不过,它们永远不会出现在 Keyboard.Modifiers 中,因为它们是为全局快捷键保留的,所以我不会在那里处理它们。

我还使用了 StringBuilder 来避免创建太多 < code>string 实例。

此解决方案适用于任何组合键,但 Shift+Alt 除外(在这种情况下看不到 Alt 修饰符)。不过,这可能是我的终端服务器环境的产物,因此您的情况可能会有所不同。

最后,我在窗口中添加了一个 _File 菜单,看看会发生什么,并且 Alt+F 快捷键在到达菜单之前就被文本框有效地捕获了,这似乎就是你想要的。

The trick is to use the SystemKey property if the Key property is set to Key.System:

private void ShortcutTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    // The text box grabs all input.
    e.Handled = true;

    // Fetch the actual shortcut key.
    Key key = (e.Key == Key.System ? e.SystemKey : e.Key);

    // Ignore modifier keys.
    if (key == Key.LeftShift || key == Key.RightShift
        || key == Key.LeftCtrl || key == Key.RightCtrl
        || key == Key.LeftAlt || key == Key.RightAlt
        || key == Key.LWin || key == Key.RWin) {
        return;
    }

    // Build the shortcut key name.
    StringBuilder shortcutText = new StringBuilder();
    if ((Keyboard.Modifiers & ModifierKeys.Control) != 0) {
        shortcutText.Append("Ctrl+");
    }
    if ((Keyboard.Modifiers & ModifierKeys.Shift) != 0) {
        shortcutText.Append("Shift+");
    }
    if ((Keyboard.Modifiers & ModifierKeys.Alt) != 0) {
        shortcutText.Append("Alt+");
    }
    shortcutText.Append(key.ToString());

    // Update the text box.
    _ShortcutTextBox.Text = shortcutText.ToString();
}

I added the left and right Windows keys to the modifier list, because they sometimes appeared in the shortcut key name when a complex (Ctrl+Shift+Alt) key combination was typed from a Terminal Server session. They're never present in Keyboard.Modifiers, though, since they're reserved for global shortcuts, so I don't handle them there.

I also used a StringBuilder to avoid creating too many string instances.

This solution works with any key combination, except Shift+Alt (the Alt modifier is not seen in that case). That might be an artifact of my Terminal Server environment, though, so your mileage may vary.

Finally, I added a _File menu to the window to see what would happen, and the Alt+F shortcut key is effectively trapped by the text box before it reaches the menu, which seems to be what you want.

只为一人 2024-08-26 15:50:20


如果您在应用程序中使用了 WPF-Command,您可以使用以下命令:

<Window.InputBindings>
  <KeyBinding Command="YourCommnad"
              Gesture="CTRL+C" />
</Window.InputBindings>

Hi
if You used WPF-Command in your application you can use this:

<Window.InputBindings>
  <KeyBinding Command="YourCommnad"
              Gesture="CTRL+C" />
</Window.InputBindings>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文