如何使WPF菜单栏在按下alt键时可见
本文关键字:alt 何使 WPF 菜单栏 | 更新日期: 2023-09-27 18:01:52
今天我在我的WPF用户界面上得到了一些新的限制,这些限制应该会消除菜单栏的永久可见性。
我想模仿Windows Live Messenger的用户界面。该应用程序仅在按下alt键时才显示菜单栏。并在菜单栏的焦点丢失时再次隐藏它。
目前我不知道如何在WPF中构建这样的东西…这样的事情可能发生吗?
你可以在主窗口写一个按键事件…
KeyDown="Window_KeyDown"
和file..
后面的代码 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>
我认为正确的实现是KeyUp。这是IE8, Vista, Windows7和其他最近的微软产品的行为:
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;
}
}
试试下面的解决方案——一个更好、更紧凑的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;
我是这么理解的:
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
}
}
如果你需要一些不同的东西玩一点键盘和鼠标事件
你可以使用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!
}
}
}