¿Cómo cambiar el tamaño de los controles separados por un divisor más allá del tamaño del panel del contenedor?

StackOverflow https://stackoverflow.com/questions/1817453

  •  08-07-2019
  •  | 
  •  

Pregunta

Tengo algunos UserControls en un panel separado por divisores. El panel contenedor está configurado en AutoScroll.

Dado que el control Splitter toma en cuenta el tamaño de su padre cuando cambia el tamaño de los controles que 'divide', el cambio de tamaño de los UserControls en su interior está limitado por el tamaño del panel.

Quiero poder mover el divisor hacia abajo donde estaba el mouse (incluso más allá de los límites del contenedor / formulario) cuando el usuario lo suelta, y hacer que el panel del contenedor cambie de tamaño en consecuencia (y muestre las barras de desplazamiento si es necesario) .

He intentado todo tipo de combinaciones envolviéndolo con diferentes paneles, jugando con MinSize, etc. Esto es lo mejor que se me ocurrió hasta ahora, pero no es lo que quiero:

texto alternativo ??

¿Alguien tiene alguna idea?

¿Fue útil?

Solución

Puede establecer un gancho de ratón cuando se presiona el botón del mouse y se desengancha cuando se suelta el botón del mouse. En la devolución de llamada de enlace, puede ver la posición del mouse y cambiar el tamaño del control según corresponda.

Editar:

En su lugar, podría usar un control especial que el usuario puede arrastrar para mantener la posición de desplazamiento en la esquina inferior derecha del contenedor principal. El usuario podría arrastrar el control para agrandar el área y, si no está utilizando la configuración de anclaje o de acoplamiento, puede ajustar manualmente el tamaño de sus controles para llenar el área principal.

Implementé algo como esto hace un tiempo para un proyecto que hice. Lo hice triangular y se parece al agarre " en un ToolStrip . Aquí hay algunos fragmentos de código del control ScrollHolder :

public ScrollHolder()
{
    this.Size = new Size(21, 21);
    this.BackColor = SystemColors.Control;
}

protected override void OnPaint(PaintEventArgs e)
{
    Point bottomLeft = new Point(0, this.Height);
    Point topRight = new Point(this.Width, 0);
    Pen controlDark = SystemPens.ControlDark;
    Pen controlLightLight = SystemPens.ControlLightLight;
    Pen controlDark2Px = new Pen(SystemColors.ControlDark, 2);
    Point bottomRight = new Point(this.Width, this.Height);
    e.Graphics.DrawLine(
        controlLightLight, 
        bottomLeft.X, 
        bottomLeft.Y - 2, 
        bottomRight.X, 
        bottomRight.Y - 2);
    e.Graphics.DrawLine(controlDark, bottomLeft, topRight);
    e.Graphics.DrawLine(
        controlLightLight, 
        bottomLeft.X + 1, 
        bottomLeft.Y, 
        topRight.X, 
        topRight.Y + 1);
    e.Graphics.DrawLine(controlDark2Px, bottomLeft, bottomRight);
    e.Graphics.DrawLine(controlDark2Px, bottomRight, topRight);
    int xNumberOfGripDots = this.Width / 4;
    for (int x = 1; x < xNumberOfGripDots; x++)
    {
        for (int y = 1; y < 5 - x; y++)
        {
            DrawGripDot(e.Graphics, new Point(
                this.Width - (y * 4), this.Height - (x * 4) - 1));
        }
    }
}

private static void DrawGripDot(Graphics g, Point location)
{
    g.FillRectangle(
        SystemBrushes.ControlLightLight, location.X + 1, location.Y + 1, 2, 2);
    g.FillRectangle(SystemBrushes.ControlDark, location.X, location.Y, 2, 2);
}

protected override void OnResize(EventArgs e)
{
    this.SetRegion();
    base.OnResize(e);
}

private void SetRegion()
{
    GraphicsPath path = new GraphicsPath();
    path.AddPolygon(new Point[] 
    { 
        new Point(this.Width, 0), 
        new Point(this.Width, this.Height),
        new Point(0, this.Height) 
    });
    this.Region = new Region(path);
}

En cuanto a la implementación del comportamiento real, es probable que desee:

  • Desplácese hasta el soporte de desplazamiento cuando se mueva fuera del área visible:
  • Al desplazarse hasta el soporte de desplazamiento, reduzca la velocidad llamando a Thread.Sleep durante un breve período de tiempo (como 50 ms).

Otros consejos

Debe establecer la propiedad MinExtra del Splitter en un número negativo grande. Si bien la propiedad en sí misma no permite esto, puede alterar el campo a través de la reflexión:

typeof(Splitter).GetField("minExtra", Reflection.BindingFlags.Instance | Reflection.BindingFlags.NonPublic).SetValue(mySplitter, -10000);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top