2012-08-30 18 views
7

Tengo un control de usuario que tiene un cuadro de texto y un cuadro de lista, y los usa para proporcionar funcionalidad de autocompletar a los usuarios.Mostrar control dentro del control de usuario fuera de los límites de su elemento primario

Sin embargo, quiero que el listbox se dibuje fuera de los límites del control de usuario para que no se corte cuando se debe dibujar el cuadro de lista cerca del borde del control de usuario. ¿Algún consejo sobre cómo hacer eso? Básicamente, quiero un cuadro de lista flotando fuera de los límites de su control contenedor.

La única forma en que puedo pensar es pasar una referencia a un cuadro de lista externo al control de usuario en la instanciación y luego manipular ese cuadro de lista en lugar de tenerlo dentro del control de usuario, pero no me gusta este enfoque. Gracias por adelantado.

+0

¿Cómo que por límites de el control del usuario? –

+0

@BenRobinson: el cuadro de texto se expande para completar el control del usuario. Si el usuario está escribiendo cerca del borde del cuadro de texto, básicamente está escribiendo cerca del borde del control del usuario. Si muestro un cuadro de lista en la posición del cursor, se cortará por el límite de control del usuario. No quiero que eso suceda. – user1391664

+0

Lo siento, no leí tus etiquetas, estaba pensando en los controles de usuario asp.net –

Respuesta

5

El problema es que no puede escapar de los límites de sus formularios de contenedor, pero puede alojar su control en otro lugar.

Aquí es lo que tengo trabajo mediante el abuso de la clase ToolStripDropDown (lo uso para mostrar datepickers en una aplicación de grandes empresas):

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

Uso:

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

     m_popup.Show(this); 
    } 
+0

Sí, esto funcionó. Gracias. – user1391664

Cuestiones relacionadas