如何让 WPF 菜单栏在按下 ALT 键时可见?

发布于 2024-11-24 06:11:16 字数 198 浏览 4 评论 0原文

今天,我的 WPF 用户界面受到了一些新的限制,这些限制应该会消除菜单栏的永久可见性。

我想到模仿 Windows Live Messenger 的用户界面。仅当按下 ALT 键时,该应用程序才会显示菜单栏。当菜单栏上的焦点丢失时,它会再次隐藏。

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

提前致谢。

Today I got some new restrictions on my WPF user interface that should eliminate the permanent visibility of the MenuBar.

I thought of imitating the user interface of Windows Live Messenger. That application displays the MenuBar only if the ALT-key is pressed. And hides it again when the focus on the MenuBar is lost.

Currently I don't have a clue how to build such a thing in WPF... is something like this possible?

Thanks in advance.

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

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

发布评论

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

评论(5

苍风燃霜 2024-12-01 06:11:26

您可以使用 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!
        }
    }
}

You can use the KeyDown (or Preview version if you prefer) and then check for the System key like this:

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!
        }
    }
}
风苍溪 2024-12-01 06:11:21

这就是我的理解:

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
    }
}

如果您需要一些不同的东西,请使用键盘和鼠标事件进行一些操作。

This is what I understood:

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
    }
}

If you need something different play a little with keyboard and mouse events.

淑女气质 2024-12-01 06:11:20

尝试以下解决方案 - 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 逻辑而不是视图模型逻辑。

在 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;

Try the following solution - a better and more compact solution in WPF. This also works if your control has not the focus or if you programatically enter the menu mode via InputManager.Current.PushMenuMode(menuSite); (see the end of the post).

Add the following code to your window or user control which contains your menu myMenu - for example at the end of your constructor:

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

Then implement the event handler:

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

Consider the following notes:

  • Set Height=0 instead of Visiblity to Collapsed/Hidden, because if the menu is invisible then the menu mode may not will be entered when Alt key will be pressed.
  • The menu must contains at least ony item, otherwise the menu mode may not will be entered when Alt key will be pressed.
  • In my opinion this solution also applies to MVVM applications, because its UI logic and not View Model logic.

Tested with target framework .NET Framework 4.5 within a WPF app on a Windows 10 machine.

Added:

If you want to enter the menu mode programmatically you can call the menu mode via: InputManager.Current.PushMenuMode(menuSite); However I had the issue that if I call the method PushMenuMode that after then the menu mode never will be leaved. So I fixed this with following solution:

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;
笙痞 2024-12-01 06:11:19

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

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>

You can write a key down event on main window..

KeyDown="Window_KeyDown"

and in the code behind file..

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

if you want to achive this with MVVM or using bindings... you can use input key bindings

 <Window.InputBindings>
        <KeyBinding Key="LeftAlt" Command="{Binding ShowMenuCommand}"/>
        <KeyBinding Key="RightAlt" Command="{Binding ShowMenuCommand}"/>
    </Window.InputBindings>
娇纵 2024-12-01 06:11:19

我认为正确的实现是使用 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;
        }
    }

I think that the correct implementation is with KeyUp. This is the behaviour of IE8, Vista, Windows7 and other recent MS products:

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;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文