Show control inside user control outside the boundaries of its parent

人走茶凉 提交于 2019-12-04 01:15:15

问题


I have a usercontrol that has a textbox and a listbox, and it uses them to provides autocomplete functionality to the users.

However, I want the listbox to be drawn outside of the boundaries of the user control so that it doesn't get cutoff when the listbox has to be drawn near the edge of the user control. Any tips on how to do that? Essentially I want a listbox floating outside the boundaries of its container control.

The only way I can think off is to pass a reference to an outside listbox to the user control on instantiation and then manipulate that listbox instead of having it inside the user control, but I dont like this approach. Thanks in advance.


回答1:


Problem is, you can't escape your container form bounds, but you can host your control somewhere else.

Here's what I got working by abusing the ToolstripDropDown class (I use it to display datepickers in a large enterprise application):

/// <summary>
/// PopupHelper
/// </summary>
public sealed class PopupHelper : IDisposable
{
    private readonly Control m_control;
    private readonly ToolStripDropDown m_tsdd;
    private readonly Panel m_hostPanel; // workarround - some controls don't display correctly if they are hosted directly in ToolStripControlHost

    public PopupHelper(Control pControl)
    {
        m_hostPanel = new Panel();
        m_hostPanel.Padding = Padding.Empty;
        m_hostPanel.Margin = Padding.Empty;
        m_hostPanel.TabStop = false;
        m_hostPanel.BorderStyle = BorderStyle.None;
        m_hostPanel.BackColor = Color.Transparent;

        m_tsdd = new ToolStripDropDown();
        m_tsdd.CausesValidation = false;

        m_tsdd.Padding = Padding.Empty;
        m_tsdd.Margin = Padding.Empty;
        m_tsdd.Opacity = 0.9;

        m_control = pControl;
        m_control.CausesValidation = false;
        m_control.Resize += MControlResize;

        m_hostPanel.Controls.Add(m_control);

        m_tsdd.Padding = Padding.Empty;
        m_tsdd.Margin = Padding.Empty;

        m_tsdd.MinimumSize = m_tsdd.MaximumSize = m_tsdd.Size = pControl.Size;

        m_tsdd.Items.Add(new ToolStripControlHost(m_hostPanel));
    }

    private void ResizeWindow()
    {
        m_tsdd.MinimumSize = m_tsdd.MaximumSize = m_tsdd.Size = m_control.Size;
        m_hostPanel.MinimumSize = m_hostPanel.MaximumSize = m_hostPanel.Size = m_control.Size;
    }

    private void MControlResize(object sender, EventArgs e)
    {
        ResizeWindow();
    }

    /// <summary>
    /// Display the popup and keep the focus
    /// </summary>
    /// <param name="pParentControl"></param>
    public void Show(Control pParentControl)
    {
        if (pParentControl == null) return;

        // position the popup window
        var loc = pParentControl.PointToScreen(new Point(0, pParentControl.Height));
        m_tsdd.Show(loc);
        m_control.Focus();
    }

    public void Close()
    {
        m_tsdd.Close();
    }

    public void Dispose()
    {
        m_control.Resize -= MControlResize;

        m_tsdd.Dispose();
        m_hostPanel.Dispose();
    }
}

Usage:

    private PopupHelper m_popup;
    private void ShowPopup()
    {
        if (m_popup == null)
            m_popup = new PopupHelper(yourListControl);

        m_popup.Show(this);
    }


来源:https://stackoverflow.com/questions/12199235/show-control-inside-user-control-outside-the-boundaries-of-its-parent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!