PopupButton won't stay open on click

Ribbon for WPF Forum

Posted 10 years ago by Nenad Lakinski
Version: 9.1.0500
Avatar
What can I do to get a popup button to stay open on click? The popup button is inside a menu (that's inside another popupbutton) and host a menu itself. I want to keep the menu open when the user clicks on the popupbutton.

PopupButton
  PopupContent = Menu
                   Button
                   Button
                   PopupButton   -> this one closes the entire menu on click.
                     PopupContent = Menu
                                      Button
                                      Button
I tried StaysOpenOnClick, handling the MouseDown, MouseClick, LostMouseCapture (and their respective Preview counterparts) but nothing works.

Is the menu hierarchy incorrect?

Nenad

Comments (7)

Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Nenad,

Please email us a simple sample project that shows the problem and we'll take a look at it. The hierarchy looks ok. Thanks!


Actipro Software Support

Posted 10 years ago by Nenad Lakinski
Avatar
Apologies, I didn't give enough context earlier. I need to generate the content of the PopupButton menu when the user clicks it.

For example if I add a static menu like this it works fine:

            PopupButton button = new PopupButton();
            button.Label = "TEST";
            button.PopupContent = new ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu();
            ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu menu = button.PopupContent as ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu;
            menu.Items.Add("outside");
            menu.Items.Add("outside2");

            PopupButton test = new PopupButton();
            test.Label = "test";
            test.StaysOpenOnClick = false;
            test.PopupContent = new ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu();
            ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu menu2 = test.PopupContent as ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu;
            menu2.Items.Add("inside");
            menu2.Items.Add("inside2");
            menu.Items.Add(test);
            this.Content = button;
This doesn't though:

            PopupButton button = new PopupButton();
            button.Label = "TEST";
            button.PreviewMouseDown += (s, ev) =>
            {
                button.PopupContent = new ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu();
                ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu menu = button.PopupContent as ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu;
                menu.Items.Add("outside");
                menu.Items.Add("outside2");

                PopupButton test = new PopupButton();
                test.Label = "test";
                test.StaysOpenOnClick = false;
                test.PopupContent = new ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu();
                ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu menu2 = test.PopupContent as ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu;
                menu2.Items.Add("inside");
                menu2.Items.Add("inside2");
                menu.Items.Add(test);
            };
            this.Content = button;
Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Nenad,

The problem here is that we look up the parent chain when a click occurs to see if it is outside of the popup. In your second case, the outer Menu doesn't have a parent yet whereas in the first case it does. So our code therefore thinks it's not in the same tree of objects and closes the root popup.

I had tried UpdateLayout calls, etc. on the root Menu but it still never seems to have the parent by the time the mouse down code is called. So unfortunately I'm not sure what else you could do here other than possibly having your Menu already in there at startup and maybe filling it on the fly instead. I didn't test that scenario though.


Actipro Software Support

Posted 10 years ago by Nenad Lakinski
Avatar
Do you mean fill these items in on the fly:

PopupButton
  PopupContent = Menu
                   Button
                   Button
                   PopupButton
                     PopupContent = Menu
                                      <generate on the fly>
                                      <generate on the fly>
If so, that won't work for me since there a many sub-popupbuttons I create and they are all dynamic. Is there a way to put myself on top of the event chain for PreviewMouseDown and execute code before you walk to control tree?
Posted 10 years ago by Nenad Lakinski
Avatar
OK, I can hack this by generating the menu on MouseEnter for the top-level PopupButton.

Thanks for the assistance,
Nenad Lakinski
Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
I just meant do this instead:
PopupButton button = new PopupButton();
button.Label = "TEST";
button.PopupContent = new ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu();
button.PreviewMouseDown += (s, ev) =>
{
    ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu menu = button.PopupContent as ActiproSoftware.Windows.Controls.Ribbon.Controls.Menu;
...
Seems to work here. All I did was add the root Menu before the delegate instead of in it. You still can add content to it on the fly in the delegate.


Actipro Software Support

Posted 10 years ago by Nenad Lakinski
Avatar
Yeah, problem is I have more than one sub-menu to generate, and I don't know how many upfront.... Anyway the MouseEnter hack works fine, I'll stick with that for now.
The latest build of this product (v2018.1 build 0675) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.