如何在按下ALT键时显示WPF菜单栏?

时间:2011-07-13 12:53:38

标签: c# .net wpf menubar

今天我的WPF用户界面有了一些新的限制,应该会消除MenuBar的永久可见性。

我想过模仿Windows Live Messenger的用户界面。仅当按下ALT键时,该应用程序才会显示MenuBar。当对MenuBar的关注丢失时再次隐藏它。

目前我还不知道如何在WPF中构建这样的东西...这样的事情可能吗?

提前致谢。

5 个答案:

答案 0 :(得分:4)

您可以在主窗口上写下按键事件..

KeyDown="Window_KeyDown"

并在文件后面的代码..

 private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.LeftAlt || e.Key == Key.RightAlt)
            {
                myMenu.Visibility = Visibility.Visible;
            }
        }

如果你想用MVVM或使用绑定来实现这个...你可以使用输入键绑定

 <Window.InputBindings>
        <KeyBinding Key="LeftAlt" Command="{Binding ShowMenuCommand}"/>
        <KeyBinding Key="RightAlt" Command="{Binding ShowMenuCommand}"/>
    </Window.InputBindings>

答案 1 :(得分:1)

我认为正确的实现是使用KeyUp。这是IE8,Vista,Windows7和其他最近的MS产品的行为:

private void MainWindow_KeyUp(Object sender, KeyEventArgs e)
    {
        if (e.Key == Key.System)
        {
            if (mainMenu.Visibility == Visibility.Collapsed)
                mainMenu.Visibility = Visibility.Visible;
            else
                mainMenu.Visibility = Visibility.Collapsed;
        }
    }

答案 2 :(得分:0)

这就是我所理解的:

private void form_KeyDown(object sender, 
    System.Windows.Forms.KeyEventArgs e)
{
    if(e.KeyCode == Keys.Alt && /*menu is not displayed*/) 
    {
        // display menu
    } 
}

private void form_KeyUp(object sender,
    System.Windows.Forms.MouseEventArgs e)
{
    if (/*check if mouse is NOT over menu using e.X and e.Y*/)
    {
        // hide menu
    }
}

如果你需要一些与键盘和鼠标事件不同的东西。

答案 3 :(得分:0)

您可以使用KeyDown(如果您愿意,可以使用预览版本),然后检查系统密钥,如下所示:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.KeyDown += new KeyEventHandler(MainWindow_KeyDown);
    }

    void MainWindow_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.System && (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
        {
            // ALT key pressed!
        }
    }
}

答案 4 :(得分:0)

请尝试以下解决方案-WPF中更好,更紧凑的解决方案。如果您的控件没有焦点,或者您通过InputManager.Current.PushMenuMode(menuSite);以编程方式进入菜单模式,也可以使用此方法(请参见文章末尾)。

将以下代码添加到包含菜单myMenu的窗口或用户控件中-例如,在构造函数的末尾:

this.myMenu.Height = 0; // Initially hide the menu
InputManager.Current.EnterMenuMode += this.InputManager_MenuModeToggled;
InputManager.Current.LeaveMenuMode += this.InputManager_MenuModeToggled;

然后实现事件处理程序:

private void InputManager_MenuModeToggled(object sender, EventArgs e)
{
    if (!InputManager.Current.IsInMenuMode)
        this.myMenu.Height = 0; // 0 to hide the menu
    else
        this.myMenu.Height = double.NaN; // NaN to reset the height (auto height)
}

请注意以下注意事项:

  • Height=0而不是Visiblity设置为Collapsed / Hidden,因为如果菜单不可见,则在按下Alt键时可能不会进入菜单模式
  • 菜单中至少应包含一个项目,否则当按Alt键时可能不会进入菜单模式。
  • 我认为该解决方案也适用于MVVM应用程序,因为它的UI逻辑而不是View Model逻辑。

在Windows 10计算机上的WPF应用程序中使用目标框架.NET Framework 4.5进行了测试。

已添加:

如果要以编程方式进入菜单模式,则可以通过以下方式调用菜单模式:InputManager.Current.PushMenuMode(menuSite);但是我遇到的问题是,如果我调用方法PushMenuMode,则之后的菜单模式将永远不会离开所以我用以下解决方案解决了这个问题:

PresentationSource source = PresentationSource.FromVisual(this);
InputManager.Current.PushMenuMode(menuSite: source);
this.Menu.Focus();

RoutedEventHandler lostFocus = null;
lostFocus = (s, args) =>
{
    InputManager.Current.PopMenuMode(menuSite: source);
    this.Menu.LostFocus -= lostFocus;
};
this.Menu.LostFocus += lostFocus;