Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PopupBox with Menu cascading #3348

Closed
jurot8 opened this issue Oct 26, 2023 · 3 comments
Closed

PopupBox with Menu cascading #3348

jurot8 opened this issue Oct 26, 2023 · 3 comments
Labels
bug evaluation required Items is pending review or evaluation by the team Waiting on feedback Additional information is needed. Stale items with this label may be closed.

Comments

@jurot8
Copy link

jurot8 commented Oct 26, 2023

Bug explanation

I have PopupBox with Menu as follows:

<md:PopupBox>
   <Menu>
     <Menu.ItemsPanel>
       <ItemsPanelTemplate>
         <StackPanel />
       </ItemsPanelTemplate>
     </Menu.ItemsPanel>

     ......


  <MenuItem Header="Parent">
       <MenuItem Header="Child" />
  </MenuItem>

....

The result:
image

...it is not cascading - the Parent-item doesn't have the arrow to open the Child.

Version

4.9.0

@jurot8 jurot8 added bug evaluation required Items is pending review or evaluation by the team labels Oct 26, 2023
@jurot8 jurot8 changed the title PopupBox with Menu cascadint PopupBox with Menu cascading Oct 26, 2023
@nicolaihenriksen
Copy link
Contributor

nicolaihenriksen commented Oct 27, 2023

@jurot8 Although this may seem like an issue with MDIX, I don't see it that way. The PopupBox allows you to specify content which is shown inside of a Popup. If/when you simply place a Menu element directly in there, it will act the same as if you placed it directly in a Window; namely by adding a clickable "button" for the root level MenuItem which in turn will open a Popup (similar to a ContextMenu) with its child MenuItem(s). So this is the result you're getting with your current code.

Based on your screen shot, it seems like you could benefit from just using a normal Button and then popping a ContextMenu when it is clicked. You could fairly easily encapsulate this into a custom control for better reuse.

Some XAML like this:

<Button Click="MyButton_OnClick">
  <Button.Resources>
    <ContextMenu x:Key="ButtonMenu" Placement="Bottom">
      <MenuItem Header="Parent">
        <MenuItem Header="Child" />
      </MenuItem>
    </ContextMenu>
  </Button.Resources>
  <materialDesign:PackIcon Kind="MoreVert" />
</Button>

and a bit of code-behind with the click handler like this:

private void MyButton_OnClick(object sender, RoutedEventArgs e)
{
    if (sender is not Button button)
        return;

    var menu = (ContextMenu) button.FindResource("ButtonMenu");
    menu.PlacementTarget = button;
    menu.IsOpen = true;
}

Naturally you probably want a different way of assigning and locating the actual ContextMenu resource since you probably don't want the same for all buttons. If you do a custom control, this would be straight-forward by simply exposing one or more DependencyProperty allowing full control from the call site.

End result is something like this (you could style the button any way you want):
CustomPopupBox

@nicolaihenriksen nicolaihenriksen added the Waiting on feedback Additional information is needed. Stale items with this label may be closed. label Oct 27, 2023
@nicolaihenriksen
Copy link
Contributor

If you do a custom control...

Perhaps this is not trivial for everyone, so I decided to add a quick example in here.

Custom control could look like this:

public class MyPopupButton : Button
{
    public static readonly DependencyProperty PopupContentProperty = DependencyProperty.Register(
        nameof(PopupContent), typeof(ContextMenu), typeof(MyPopupButton), new PropertyMetadata(default(ContextMenu)));

    public ContextMenu? PopupContent
    {
        get { return (ContextMenu) GetValue(PopupContentProperty); }
        set { SetValue(PopupContentProperty, value); }
    }

    protected override void OnClick()
    {
        if (PopupContent is null)
            return;

        PopupContent.PlacementTarget = this;
        PopupContent.IsOpen = true;
    }
}

And usage from XAML would then be something like this:

<local:MyPopupButton Style="{StaticResource MaterialDesignPopupBoxButton}">
  <local:MyPopupButton.PopupContent>
    <ContextMenu Placement="Bottom">
      <MenuItem Header="Parent">
        <MenuItem Header="Child" />
      </MenuItem>
    </ContextMenu>
  </local:MyPopupButton.PopupContent>
  <materialDesign:PackIcon Kind="MoreVert" />
</local:MyPopupButton>

Here I have simply used the MaterialDesignPopupBoxButton style to make it appear similar to the PopupBox, again you can add your own flavor to it.

End result will look something like this:
CustomPopupBox2

@jurot8
Copy link
Author

jurot8 commented Oct 30, 2023

Thanks, that's exactly what I need.

@jurot8 jurot8 closed this as completed Oct 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug evaluation required Items is pending review or evaluation by the team Waiting on feedback Additional information is needed. Stale items with this label may be closed.
Projects
None yet
Development

No branches or pull requests

2 participants