Question

Not sure how to explain this, but:

  • there is a control MyPopup, made out of ToolStripDropDown;
  • there are many based on MyPopup controls (call them popups);
  • there are no problems to open popup from the Form;
  • but there is is a problem to open popup from popup.

Problem is what after child popup is closed, parent popup stays on screen even when its parent Form get focus. The only way to close that stuck parent popup is to get focus to it (with the mouse) and hit Esc.

To have popup able to show another popup I have to trick Closing event:

    void Popup_Closing(object sender, ToolStripDropDownClosingEventArgs e)
    {
        // prevent from closing when stay
        if (_stay && e.CloseReason != ToolStripDropDownCloseReason.CloseCalled )
        {
            e.Cancel = true;
            return;
        }
    }

Before of after closing child popup, parent popup has:

  • value of _stay is False;
  • the value of Popup.AutoClose is True;

I tried to "bring" mouse focus back to the parent popup with the following:

  • TopLevel=true no luck;
  • Focus(); no luck;
  • Focused=true; no luck;
  • AutoClose=true; no luck;
  • Captured=true; no luck;

Also tried setting above value to False and then to True, still no luck.

And here is some more code, which could be useful or not:

public class MyPopup : UserControl
{
    protected bool _stay = false;

    private ToolStripDropDown _popup;
    private ToolStripControlHost _host;

    public MyPopup()
    {
        // create popup
        _popup = new ToolStripDropDown();
        _popup.Margin = _popup.Padding = Padding.Empty;
        _popup.AutoSize = false;
        _popup.Closing += Popup_Closing;
        // add host
        _host = new ToolStripControlHost(this);
        _host.Margin = _host.Padding = Padding.Empty;
        _host.AutoSize = false;
        _popup.Items.Add(_host);
    }

    public void Show(Control parent, int x, int y)
    {
        _popup.Show(parent, x, y);
    }

    public new void Hide()
    {
        _popup.Close();
    }

    private void Popup_Closing(object sender, ToolStripDropDownClosingEventArgs e)
    {
        // prevent from closing when stay
        if (_stay && e.CloseReason != ToolStripDropDownCloseReason.CloseCalled )
        {
            e.Cancel = true;
            return;
        }
    }

    protected void PopupChildClosedDefaultEvent(object sender, EventArgs e)
    {
        // hide popup if mouse is outside of client region when closing child popup
        if (!ClientRectangle.Contains(PointToClient(MousePosition)))
            Hide();
        else
        {
            // >> here I am trying different things <<
            _popup.AutoClose = false;
            _popup.AutoClose = true;
        }
    }
}

public class PopupParent: MyPopup
{
    private void TestChildren()
    {
        _stay = true;
        PopupChild popup = new PopupChild();
        popup.Show(button1, 0, 0);
        popup.Closed += PopupChildClosedDefaultEvent;
        _stay = false;
    }
}

public class PopupChild: MyPopup
{
}

Question: Is there any way to fix "broken" popup after it has lost its ability to autoclose on mouse event (clicking somewhere outside of the client area)?

Was it helpful?

Solution

Ok, morning bring some freshness to brains and I managed to solve that issue with following:

            _popup.Close();
            _popup.Show(_parent, _x, _y);

So I have to reshow popup to have it functioning as before. It flickers, but works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top