Показать элемент управления внутри пользовательского элемента управления за пределами его родительского элемента

У меня есть пользовательский элемент управления с текстовым полем и списком, и он использует их для предоставления пользователям функций автозаполнения.

Однако я хочу, чтобы список отображался за пределами пользовательского элемента управления, чтобы он не обрезался, когда список должен быть нарисован рядом с краем пользовательского элемента управления. Любые советы о том, как это сделать? По сути, я хочу, чтобы список выходил за пределы его контейнерного элемента управления.

Единственный способ, который я могу придумать, - это передать ссылку на внешний список в пользовательский элемент управления при создании экземпляра, а затем манипулировать этим списком вместо того, чтобы иметь его внутри пользовательского элемента управления, но мне не нравится этот подход. Заранее спасибо.


person user1391664    schedule 30.08.2012    source источник
comment
Что вы подразумеваете под границами пользовательского контроля?   -  person Ben Robinson    schedule 30.08.2012
comment
@BenRobinson: текстовое поле расширяется, чтобы заполнить пользовательский элемент управления. Если пользователь печатает рядом с краем текстового поля, он, по сути, печатает рядом с краем пользовательского элемента управления. Если я покажу список в позиции курсора, он будет обрезан границей пользовательского контроля. Я не хочу, чтобы это произошло.   -  person user1391664    schedule 30.08.2012
comment
Извините, я не прочитал ваши теги, я думал, что пользовательские элементы управления asp.net   -  person Ben Robinson    schedule 30.08.2012


Ответы (1)


Проблема в том, что вы не можете выйти за пределы формы контейнера, но вы можете разместить свой элемент управления в другом месте.

Вот что у меня получилось, злоупотребив классом 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);
    }
person Vedran    schedule 30.08.2012
comment
для нескольких элементов управления - person Ravi; 23.07.2019