使 wpf 元素在失去焦点时隐藏
Make a wpf element hide when it loses focous
我有一个 WPF 菜单栏,它在程序启动时折叠起来,可以通过按 F10(如 Firefox)显示
<Menu x:Name="mainMenuBar" Height="20" Width="130" HorizontalAlignment="Left" DockPanel.Dock="Top" FocusManager.LostFocus="mainMenuBar_LostFocus">
我有一些代码,如果它失去焦点(即用户单击菜单栏和子菜单以外的其他地方),我会使用 FocusManager.LostFocus
属性.
private void showMenuBar(object sender, KeyEventArgs e)
{
if(e.SystemKey == Key.F10)
{
mainMenuBar.Visibility = Visibility.Visible;
mainMenuBar.Focus();
}
}
private void mainMenuBar_LostFocus(object sender, RoutedEventArgs e)
{
mainMenuBar.Visibility = Visibility.Collapsed;
}
当我点击菜单栏以外的地方时它不会折叠,但当我点击菜单栏时它会折叠。这种行为与我的预期相反,有人知道为什么会这样吗?
编辑:XAML代码
<Menu x:Name="mainMenuBar" Height="20" Width="130" HorizontalAlignment="Left" DockPanel.Dock="Top">
<MenuItem Header="File">
<Separator />
<MenuItem Header="Exit" Click="menuFileExit_Click" ToolTip="Close Program" />
</MenuItem>
<MenuItem Header="Options">
<MenuItem Header="Settings" Click="menuOptionsSettings_Click" />
</MenuItem>
<MenuItem Header="Help">
<MenuItem Header="Read Me" Click="menuHelpReadMe_Click" />
<MenuItem Header="Version History" Click="menuHelpVersionHistory_Click" />
<MenuItem Header="About" Click="menuHelpAbout_Click" />
</MenuItem>
</Menu>
我找到了获得所需行为的方法。
像您一样显示菜单,但即使不设置焦点。
protected override void OnKeyDown(KeyEventArgs e)
{
if(e.SystemKey == Key.F10)
{
mainMenuBar.Visibility = Visibility.Visible;
}
base.OnKeyDown(e);
}
在您的菜单所在的 window 覆盖 OnPreviewMouseDown
。
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
if (mainMenuBar.IsVisible && e.Source != mainMenuBar&& !IsMenuChildMouseDown(e.Source as FrameworkElement))
{
mainMenuBar.Visibility = Visibility.Collapsed;
}
base.OnPreviewMouseDown(e);
}
并创建方法 IsMenuChildMouseDown(FrameworkElement elem)
以检查鼠标是否在子菜单上按下。
private bool IsMenuChildMouseDown(FrameworkElement elem)
{
if (elem == null)
return false;
DependencyObject parent = elem.Parent;
if (parent == null)
return false;
else
{
if (parent == mainMenuBar)
return true;
return IsMenuChildMouseDown(parent as FrameworkElement);
}
}
我有一个 WPF 菜单栏,它在程序启动时折叠起来,可以通过按 F10(如 Firefox)显示
<Menu x:Name="mainMenuBar" Height="20" Width="130" HorizontalAlignment="Left" DockPanel.Dock="Top" FocusManager.LostFocus="mainMenuBar_LostFocus">
我有一些代码,如果它失去焦点(即用户单击菜单栏和子菜单以外的其他地方),我会使用 FocusManager.LostFocus
属性.
private void showMenuBar(object sender, KeyEventArgs e)
{
if(e.SystemKey == Key.F10)
{
mainMenuBar.Visibility = Visibility.Visible;
mainMenuBar.Focus();
}
}
private void mainMenuBar_LostFocus(object sender, RoutedEventArgs e)
{
mainMenuBar.Visibility = Visibility.Collapsed;
}
当我点击菜单栏以外的地方时它不会折叠,但当我点击菜单栏时它会折叠。这种行为与我的预期相反,有人知道为什么会这样吗?
编辑:XAML代码
<Menu x:Name="mainMenuBar" Height="20" Width="130" HorizontalAlignment="Left" DockPanel.Dock="Top">
<MenuItem Header="File">
<Separator />
<MenuItem Header="Exit" Click="menuFileExit_Click" ToolTip="Close Program" />
</MenuItem>
<MenuItem Header="Options">
<MenuItem Header="Settings" Click="menuOptionsSettings_Click" />
</MenuItem>
<MenuItem Header="Help">
<MenuItem Header="Read Me" Click="menuHelpReadMe_Click" />
<MenuItem Header="Version History" Click="menuHelpVersionHistory_Click" />
<MenuItem Header="About" Click="menuHelpAbout_Click" />
</MenuItem>
</Menu>
我找到了获得所需行为的方法。 像您一样显示菜单,但即使不设置焦点。
protected override void OnKeyDown(KeyEventArgs e)
{
if(e.SystemKey == Key.F10)
{
mainMenuBar.Visibility = Visibility.Visible;
}
base.OnKeyDown(e);
}
在您的菜单所在的 window 覆盖 OnPreviewMouseDown
。
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
if (mainMenuBar.IsVisible && e.Source != mainMenuBar&& !IsMenuChildMouseDown(e.Source as FrameworkElement))
{
mainMenuBar.Visibility = Visibility.Collapsed;
}
base.OnPreviewMouseDown(e);
}
并创建方法 IsMenuChildMouseDown(FrameworkElement elem)
以检查鼠标是否在子菜单上按下。
private bool IsMenuChildMouseDown(FrameworkElement elem)
{
if (elem == null)
return false;
DependencyObject parent = elem.Parent;
if (parent == null)
return false;
else
{
if (parent == mainMenuBar)
return true;
return IsMenuChildMouseDown(parent as FrameworkElement);
}
}