如何在WPF中使用Alt键切换主菜单的可见性?

8
我希望我的WPF应用程序中的主菜单的行为类似于IE8中的主菜单:
  • 应用程序启动时不可见
  • 按下并释放Alt键使其可见
  • 再次按下并释放Alt键使其变为不可见
  • 重复此操作直到厌倦
如何实现这一功能?是否需要编写代码?
在回答提交后添加,因为我仍然遇到了问题:
我的 Shell 代码现在看起来像这样:
public partial class Shell : Window
{
    public static readonly DependencyProperty IsMainMenuVisibleProperty;

    static Shell()
    {
        FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
        metadata.DefaultValue = false;

        IsMainMenuVisibleProperty = DependencyProperty.Register(
            "IsMainMenuVisible", typeof(bool), typeof(Shell), metadata);
    }

    public Shell()
    {
        InitializeComponent();

        this.PreviewKeyUp += new KeyEventHandler(Shell_PreviewKeyUp);
    }

    void Shell_PreviewKeyUp(object sender, KeyEventArgs e)
    {
        if (e.SystemKey == Key.LeftAlt || e.SystemKey == Key.RightAlt)
        {
            if (IsMainMenuVisible == true)
                IsMainMenuVisible = false;
            else
                IsMainMenuVisible = true;
        }
    }

    public bool IsMainMenuVisible
    {
        get { return (bool)GetValue(IsMainMenuVisibleProperty); }
        set { SetValue(IsMainMenuVisibleProperty, value); }
    }
}

1
你想模仿Internet Explorer吗? - Cameron MacFarland
1
我尽力使我的应用程序与用户的期望保持一致,所以是的。 :-) - serialhobbyist
为了保持一致性,最好考虑到 F10 键触发相同的行为。 - genus
5个回答

8
您可以在窗口上使用“PreviewKeyDown”事件。 要检测“Alt”键,您需要检查“KeyEventArgs”的“SystemKey”属性,而不是通常用于大多数其他键的“Key”属性。
您可以使用此事件来设置已在窗口代码后端声明为“DependencyProperty”的“bool”值。
然后,菜单的“Visibility”属性可以使用“BooleanToVisibilityConverter”绑定到此属性。
<Menu 
    Visibility={Binding Path=IsMenuVisibile, 
        RelativeSource={RelativeSource AncestorType=Window},
        Converter={StaticResource BooleanToVisibilityConverter}}
    />

我做不出来。我已经更新了原始问题,包括我的DependencyProperty的代码。这是我第一次声明自己的依赖属性。 我将你的绑定添加到了Shell.xaml中的Menu中,但我得到的错误是: System.Windows.Data Error: 39 : BindingExpression path error: 'IsMenuVisibile' property not found on 'object' ''Shell' (Name='')'. BindingExpression:Path=IsMenuVisibile; DataItem='Shell' (Name=''); target element is 'Menu' (Name='uxMainMenu'); target property is 'Visibility' (type 'Visibility')。你有什么想法吗? - serialhobbyist
这是标准的绑定错误,当属性无法找到时会出现。要修复它,您需要在绑定中将IsMenuVisible替换为IsMainMenuVisible。 - Ian Oakes
哦,我真是个白痴!我会登录并解决的。谢谢。还有谢谢你没有指出我有多蠢。 :-) - serialhobbyist
1
那就是它了。非常感谢。不仅我已经实现了(多亏你)Alt键功能和我的第一个DependencyProperty,今天我还刷了两个天花板:我想我应该趁手时退出了。 :-) - serialhobbyist

2
我刚刚遇到了这个问题。我尝试钩入 PreviewKeyDown 事件,但发现它不可靠。相反,我找到了 InputManager 类,在托管代码中可以钩入 EnterMenuMode。该管理器公开了两个事件,用于进入和退出。诀窍是不要折叠菜单,而是在隐藏时将其容器高度设置为零。要显示它,只需清除本地值,它将恢复其先前的高度。

从我的 TopMenu 用户控件:

public TopMenu()
{
    InitializeComponent();
    InputManager.Current.EnterMenuMode += OnEnterMenuMode;
    InputManager.Current.LeaveMenuMode += OnLeaveMenuMode;
    Height = 0;
}

private void OnLeaveMenuMode(object sender, System.EventArgs e)
{
    Height = 0;
}

private void OnEnterMenuMode(object sender, System.EventArgs e)
{
    ClearValue(HeightProperty);
}

1

我建议你尝试处理窗口上的PreviewKeyDown事件。我不确定按下Alt键是否会触发此事件,但如果是的话,那么我会切换一个绑定到窗口主菜单可见性的bool

如果PreviewKeyDown无法解决问题,我不确定还有什么其他方法可以尝试。你可以尝试获取发送到窗口的实际Windows消息,但这可能会很快变得混乱。


谢谢您的建议。我会采用Phil Price的建议,使用PreviewKeyUp,因为这更接近IE,但听起来可行。 - serialhobbyist

1
最好使用 GetKeyboardStateVK_MENU 一起处理左右 Alt,以模仿 IE / Windows Explorer(Vista+)的行为,您需要跟踪先前聚焦的元素以存储焦点,在主菜单中聚焦元素时按下 VK_MENU。此外,您还希望在 PreviewKeyUp 上执行此操作(而不是按下)。

谢谢。目前,我甚至无法掌握基础知识,所以我会暂时放下 WM 的事情! - serialhobbyist

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接