Pregunta

Estoy utilizando un control ToolStripDropDown para implementar la parte desplegable de una costumbre ComboBox como control. Con el fin de ser atractivo visualmente, yo estoy imponiendo un MaximumSize en el menú desplegable y especificar manualmente el ancho de cada ToolStripButton dentro de ella - el resultado es una ventana emergente que es la misma anchura que el control que lo activa, con un casquillo de la altura de la altura de la porción desplegable.

Ejemplo (simplificada):

ToolStripDropDown dropDown = new ToolStripDropDown();
dropDown.MaximumSize = new Size(200, 100);
dropDown.RenderMode = ToolStripRenderMode.System;
dropDown.AutoSize = true;

for (int i = 0; i < 50; i++) {
    ToolStripButton dropDownItem = (ToolStripButton)dropDown.Items.Add("Item " + i);
    dropDownItem.AutoSize = false;
    dropDownItem.Size = new Size(200, 20);
}

dropDown.Show(owningControl, new Point(0, owningControl.Height - 1));

Como se puede ver, se aplican las restricciones sobre el tamaño de la ventana emergente, sin embargo, el arriba / abajo botones de desplazamiento no se muestran y no parece haber ninguna manera de hacerlos aparecer. No parece haber ningún métodos o propiedades dentro de ToolStripDropDown con respecto a la de desplazamiento offset o un mecanismo para desplazarse un artículo en particular a la vista (tal como EnsureVisible() en ListViewItem).

Entonces, ¿cómo puedo obtener el menú desplegable para desplazamiento? Cualquier método sería suficiente, ya sea una barra de desplazamiento, botones de desplazamiento o incluso la rueda del ratón.

(Por cierto, he intentado muchas veces para hacer controles similares utilizando un Form para la parte desplegable - a pesar de probar docenas de soluciones para evitar que la ventana emergente de robar el foco o la obtención de enfoque cuando se hace clic en sus controles, esto parece ser una muerta final. también he descartado el uso de ToolStripControlHost, cuyo control sigue alojada puede tomar el foco lejos de la forma que lo abrió.)

¿Fue útil?

Solución

Finalmente se quebró éste. Se me ocurrió que ContextMenuStrip y ToolStripDropDownMenu son capaces del comportamiento auto-desplazamiento, que su clase base, ToolStripDropDown, no puede proporcionar. Inicialmente, evité estos controles alternativos, ya que suelen añadir un amplio margen. Esto se puede quitar a través de ShowImageMargin y ShowCheckMargin. Incluso después de hacer esto, un pequeño restos de margen (aprox 5px). Esto se puede quitar anulando la propiedad DefaultPadding:

public class MyDropDown : ToolStripDropDownMenu {

    protected override Padding DefaultPadding {
        get { return Padding.Empty; }
    }

    public MyDropDown() {
        ShowImageMargin = ShowCheckMargin = false;
        RenderMode = ToolStripRenderMode.System;
        MaximumSize = new Size(200, 150);
    }
}

// adding items and calling Show() remains the same as in the question

Esto resulta en una ventana emergente que puede contener cualquier tipo de elemento ToolStrip, hace cumplir MaximumSize, no tiene margen y, lo más importante, no roba el foco y no puede recibir el foco.

Otros consejos

Esta es su némesis:

internal virtual bool RequiresScrollButtons
{
    get
    {
        return false;
    }
    set
    {
    }
}

Es interno, no se puede anularlo. Puede reactivar su enfoque de utilizar un formulario mediante la fijación del comportamiento del foco robo. Pega esto en la clase de formulario:

protected override bool ShowWithoutActivation
{
    get { return true; }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top