WPF: button inside MenuItem, closing the menu

2019-06-21 18:00发布

I've got a Button inside a MenuItem's header. Clicking the menu item (not the Button part) closes the menu as expected, but clicking the Button doesn't close the menu, and I want it to. How can I fix this?

More background:

I have two commands that are minor variants of each other, and I want to put them both in a menu. The first variant will be used most of the time, so I don't really want two menu items both taking up space, nor do I want to put them both in a submenu. So I hit on the idea of putting a Button for the secondary command inside the MenuItem, like so:

<Menu>
  <MenuItem Header="Git">
    <MenuItem Command="{Binding PrimaryCommand}">
      <MenuItem.Header>
        <StackPanel Orientation="Horizontal">
          <TextBlock VerticalAlignment="Center" Text="Rebase "/>
          <Button Content="Interactive" Focusable="False"
                  Command="{Binding SecondaryCommand}"/>
        </StackPanel>
      </MenuItem.Header>
    </MenuItem>
  </MenuItem>
</Menu>

which looks like this:

http://www.excastle.com/misc/wpf-menuitem-with-button.png

So if I click on the button, I'll get the secondary command; but if I click anywhere else on the menu item, I'll get the primary command. This works well, up to a point.

The problem is, whether I'm clicking on the MenuItem or on the Button, I've made my selection and I want the menu to close -- but if I click the button, it doesn't close the menu. The menu stays open. I can see this actually being useful behavior in some cases (e.g. zoom in/out buttons that you might want to click multiple times without closing the menu after each click, as in Google Chrome's menu); but in this case I do want the button to close the menu.

In case anyone wonders about that Focusable="False", removing it doesn't fix the problem, it just changes it so the Button draws with a blue (focused) border the second time you drop the menu down.

I've tried using a Hyperlink instead of a Button, with the same effect: clicking the Hyperlink doesn't close the menu.

How can I get the embedded button to close the menu?

标签: wpf menu
1条回答
Deceive 欺骗
2楼-- · 2019-06-21 18:41

I've just added PreviewMouseUp event handler for menu item and close submenu of sender's parent inside handler:

<MenuItem Command="{Binding PrimaryCommand}" 
          PreviewMouseUp="MenuItem_PreviewMouseUp">
     ...
</MenuItem>


private void MenuItem_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    // add checks of null value by yourself 
    ((MenuItem)((MenuItem)sender).Parent).IsSubmenuOpen = false;
}

If you are avoiding code behind (like me), it's possible to create Behaviour for menu item.

查看更多
登录 后发表回答