8

我有一个包含文本框和列表框的用户控件,它使用它们为用户提供自动完成功能。

但是,我希望将列表框绘制在用户控件的边界之外,以便在必须在用户控件的边缘附近绘制列表框时它不会被截断。关于如何做到这一点的任何提示?本质上,我想要一个列表框浮动在其容器控件的边界之外。

我能想到的唯一方法是在实例化时将对外部列表框的引用传递给用户控件,然后操纵该列表框而不是将其放在用户控件中,但我不喜欢这种方法。提前致谢。

4

1 回答 1

7

问题是,您无法逃脱容器表单的界限,但您可以将控件托管在其他地方。

这是我通过滥用 ToolstripDropDown 类得到的工作(我用它在大型企业应用程序中显示日期选择器):

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

用法:

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

        m_popup.Show(this);
    }
于 2012-08-30T14:46:44.433 回答