简体   繁体   English

在其父级边界之外的用户控件内显示控件

[英]Show control inside user control outside the boundaries of its parent

I have a usercontrol that has a textbox and a listbox, and it uses them to provides autocomplete functionality to the users. 我有一个usercontrol,它有一个文本框和一个列表框,它使用它们为用户提供自动完成功能。

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. 提前致谢。

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): 这是我通过滥用ToolstripDropDown类(我用它来在大型企业应用程序中显示datepickers)工作的方式:

/// <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);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM