使用箭头键时 WPF 弹出菜单项保持突出显示

发布于 2024-10-20 15:34:51 字数 1314 浏览 1 评论 0原文

以编程方式打开弹出菜单后,如果用户使用向上和向下箭头键在菜单中移动,菜单项将突出显示,并且永远不会取消突出显示。我该怎么做才能在用户按下向下箭头后,先前突出显示的菜单项变得不突出显示?

这是通过一个非常简单的弹出菜单发生的:

<Grid>
    <Button x:Name="Button1" Content="Open Menu" 
            Click="OnPopupMenuButton_Click"
            Height="23" HorizontalAlignment="Left" Margin="69,12,0,0" VerticalAlignment="Top" Width="75" />

    <Popup x:Name="MyPopupMenu" StaysOpen="False" >
        <StackPanel Orientation="Vertical" Background="White" Margin="0">
            <MenuItem x:Name="xAimee" Header="Aimee" Margin="0,2,0,0" />
            <MenuItem x:Name="xBarbara" Header="Barbara" />
            <MenuItem x:Name="xCarol" Header="Carol" />
            <Separator x:Name="xSeparator1" Margin="0,2,2,2"/>
            <MenuItem x:Name="xDana" Header="Dana" />
            <MenuItem x:Name="xElizabeth" Header="Elizabeth" />
        </StackPanel>
    </Popup>
</Grid>

以下是打开弹出菜单的方式:

private void OnPopupMenuButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    Button button = sender as Button;

    MyPopupMenu.PlacementTarget = button;
    MyPopupMenu.Placement = PlacementMode.Mouse;
    MyPopupMenu.IsOpen = true;
    MyPopupMenu.StaysOpen = false;
}

After opening a Popup menu programatically, if the user uses up and down arrow keys to move through the menu, menu items get highlighted and they never get unhighlighted. What can I do so that after the user presses the down arrow, the previously highlighted menuitem becomes unhighlighted?

This happens with a very simple Popup menu:

<Grid>
    <Button x:Name="Button1" Content="Open Menu" 
            Click="OnPopupMenuButton_Click"
            Height="23" HorizontalAlignment="Left" Margin="69,12,0,0" VerticalAlignment="Top" Width="75" />

    <Popup x:Name="MyPopupMenu" StaysOpen="False" >
        <StackPanel Orientation="Vertical" Background="White" Margin="0">
            <MenuItem x:Name="xAimee" Header="Aimee" Margin="0,2,0,0" />
            <MenuItem x:Name="xBarbara" Header="Barbara" />
            <MenuItem x:Name="xCarol" Header="Carol" />
            <Separator x:Name="xSeparator1" Margin="0,2,2,2"/>
            <MenuItem x:Name="xDana" Header="Dana" />
            <MenuItem x:Name="xElizabeth" Header="Elizabeth" />
        </StackPanel>
    </Popup>
</Grid>

Here is how the Popup gets opened:

private void OnPopupMenuButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    Button button = sender as Button;

    MyPopupMenu.PlacementTarget = button;
    MyPopupMenu.Placement = PlacementMode.Mouse;
    MyPopupMenu.IsOpen = true;
    MyPopupMenu.StaysOpen = false;
}

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

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

发布评论

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

评论(1

蓝礼 2024-10-27 15:34:51

我一直在跟进阿彻的建议,但我遇到了一些问题。首先,我不想在右键单击时打开菜单,部分原因是我不想在右键单击时打开菜单,部分原因是我实际上需要使用 PlacementMode.Top,并且上下文菜单不断打开在标准上下文菜单位置(侧面和下方)。

所以最后,我确实使用了上下文菜单,但我做了一些特殊的事情。首先,在 Window 构造函数中,我将按钮的 ContextMenu 设置为 null,以防止右键单击时打开它。然后,当用户单击左键时,我以编程方式将 ContextMenu 设置为我在 xaml 文件中创建的菜单。当菜单关闭时,我将按钮的 ContextMenu 设置回 null。我尝试操作 ContextMenu 可见性,但这似乎并不像将其设置为 null 并返回到对象那样有效。

这是最终的 xaml,与我正在处理 ContextMenu 的 Closed 事件的问题异常没有太大不同。

<Button x:Name="xOpenContextMenuButton" Content = "Open Menu" 
    Click="OnContextMenuButton_Click"
    HorizontalAlignment="Right" VerticalAlignment="Bottom" 
    Width="80" Margin="0,0,36,8" Height="23">

    <Button.ContextMenu>
        <ContextMenu x:Name="xContextMenu" Closed="OnContextMenu_Closed">
            <MenuItem x:Name="xAimee" Header="Aimee" />
            <MenuItem x:Name="xBarbara" Header="Barbara" />
            <MenuItem x:Name="xCarol" Header="Carol" />
            <Separator x:Name="xSeparator1" Margin="0,2,2,2" />
            <MenuItem x:Name="xDana" Header="Dana" />
            <MenuItem x:Name="xElizabeth" Header="Elizabeth" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>

这是隐藏的代码,它发生了很大的变化:

public MainWindow()
{
    InitializeComponent();

    xOpenContextMenuButton.ContextMenu = null;
}

private void OnContextMenuButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    xOpenContextMenuButton.ContextMenu = xContextMenu;

    xContextMenu.PlacementTarget = xOpenContextMenuButton;
    xContextMenu.Placement = PlacementMode.Top;

    xContextMenu.IsOpen = true;
    xContextMenu.StaysOpen = false;
}

private void OnContextMenu_Closed(object sender, RoutedEventArgs e)
{
    xOpenContextMenuButton.ContextMenu = null;
}

再次感谢 archer,因为我没有意识到使用 Popup 不是在 WPF 中创建弹出菜单的正常方法。我认为问题的根本原因是,弹出窗口可以包含任何内容 - 标签、另一个按钮等。弹出窗口不一定需要嵌入菜单项,因此它不够智能,无法理解它应该在我的菜单之间切换使用箭头键时的项目。但是 ContextMenu 期望其中包含 MenuItems,因此它知道如何在它们之间切换。

I have been following up on archer's suggestion, but I had a few issues. First, I did not want the menu to open on a right-click, partly because I just didn't want it to open on a right-click and partly because I actually need to use PlacementMode.Top, and the context menu kept opening in the standard context-menu place (to the side and down).

So in the end, I did end up using a Context Menu, but I did a couple of special things. First, in the Window constructor, I set the button's ContextMenu to null, to prevent it from opening when right-clicked. Then when the user left-clicks, I programmatically set the ContextMenu to the one that I created in the xaml file. When the menu closes, I set the button's ContextMenu back to null. I tried manipulating the ContextMenu visibility instead, but that did not seem to work as well as setting it to null and back to an object.

Here is the final xaml, not too different from the question exception that I am handling the Closed event for the ContextMenu.

<Button x:Name="xOpenContextMenuButton" Content = "Open Menu" 
    Click="OnContextMenuButton_Click"
    HorizontalAlignment="Right" VerticalAlignment="Bottom" 
    Width="80" Margin="0,0,36,8" Height="23">

    <Button.ContextMenu>
        <ContextMenu x:Name="xContextMenu" Closed="OnContextMenu_Closed">
            <MenuItem x:Name="xAimee" Header="Aimee" />
            <MenuItem x:Name="xBarbara" Header="Barbara" />
            <MenuItem x:Name="xCarol" Header="Carol" />
            <Separator x:Name="xSeparator1" Margin="0,2,2,2" />
            <MenuItem x:Name="xDana" Header="Dana" />
            <MenuItem x:Name="xElizabeth" Header="Elizabeth" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>

Here is the code-behind, which changed a lot:

public MainWindow()
{
    InitializeComponent();

    xOpenContextMenuButton.ContextMenu = null;
}

private void OnContextMenuButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    xOpenContextMenuButton.ContextMenu = xContextMenu;

    xContextMenu.PlacementTarget = xOpenContextMenuButton;
    xContextMenu.Placement = PlacementMode.Top;

    xContextMenu.IsOpen = true;
    xContextMenu.StaysOpen = false;
}

private void OnContextMenu_Closed(object sender, RoutedEventArgs e)
{
    xOpenContextMenuButton.ContextMenu = null;
}

Once again, thanks to archer, because I didn't realize that using Popup was not the normal way to create a popup menu in WPF. I think the root cause of the problem is, a Popup can contain anything -- a label, another button, etc. Popup isn't necessarily expecting embedded MenuItems, so it isn't smart enough to understand that it should switch between my menu items when using the arrow keys. But a ContextMenu expects to have MenuItems in it so it knows how to switch between them.

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