在 WPF 工具提示中检测按键

Detect keypress in WPF Tooltip

在 WPF 中,我想创建一个自定义工具提示,打开时可以检测到 F1 键按下,以便将用户带到更详细的帮助文件。

为了可重用性,我的方法是创建一个 UserControl 作为工具提示。控件将检测 KeyDown 事件,然后执行可绑定的 Command.

但实际上 KeyDown 事件似乎从未触发过。也许工具提示不能聚焦键盘事件?我已经尝试为 UserControl 设置 KeyDown 事件,然后为 UserControl 中的子控件设置事件,无论如何都不走运。

这是带有 KeyDown 事件的 UserControl 的(一个示例):

<UserControl x:Class="HotKeyToolTip"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         KeyDown="UserControl_KeyDown">

这里是如何将此控件声明为工具提示的示例,在本例中是针对组合框的项目:

<ComboBox.ItemContainerStyle>
                    <Style>
                        <Setter Property="Control.ToolTip">
                            <Setter.Value>
                                <local:HotKeyToolTip Focusable="True"/>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ComboBox.ItemContainerStyle>

在 ToolTip/UserControl 中处理 KeyDown 很困难,因为如果 ToolTip 获得焦点,组合框将失去它,因此将关闭下拉菜单和 ToolTip。你可以看看 How to intercept all the keyboard events and prevent losing focus in a WinForms application?

我会处理 Combobox 中的 KeyDown 和 get/set 工具提示文本。为了获得更大的灵活性,我会将其实现为一种行为!

        <ComboBox.ItemContainerStyle>
            <Style TargetType="Control">
                <Setter Property="Control.ToolTip">
                    <Setter.Value>
                        <ToolTip>
                            <local:HotKeyToolTip />
                        </ToolTip>
                    </Setter.Value>
                </Setter>
            </Style>
        </ComboBox.ItemContainerStyle>


private void ComboBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key==Key.F1)
            {
                var cmb = sender as ComboBox;
                var cmbi = cmb.Items.OfType<ComboBoxItem>().ToList();
                if (cmbi != null)
                {
                    foreach (var item in cmbi)
                    {
                        var tt = item.ToolTip as ToolTip;
                        if (tt != null && tt.IsOpen && tt.PlacementTarget == item)
                        {
                            (tt.Content as HotKeyToolTip).YourToolTipText = item.Content.ToString();//item.DataContext.ToolTipExtendedText
                        }
                    }
                }
            }
        }