¿Cómo hacer que RightToLeftLayout funcione para los controles dentro de GroupBoxes y Panels?

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

  •  02-07-2019
  •  | 
  •  

Pregunta

Según MSDN

form.RightToLeftLayout = True;
form.RightToLeft = ifWeWantRTL() ? RightToLeft.True : RightToLeft.False;

es suficiente para aumentar el contenido del formulario para los idiomas RTL.

Pero la ubicación de los controles se duplica solo para los controles inmediatamente en el formulario,
los que están dentro de un GroupBox o un Panel no se duplican , a menos que los coloque en un TableLayoutPanel o en un FlowLayoutPanel fisrt.

Este es un montón de trabajo manual para colocar un TableLayoutPanel dentro de cada GroupBox, y especialmente para reorganizar los controles (un control por celda de tabla, relleno, margen, etc.)

¿Hay una manera más fácil de hacer que el reflejo funcione para todos los controles?

O al menos, ¿cómo puedo omitir el paso de reorganización, ya que es una gran tarea con nuestra cantidad de formularios?


Editar : la propiedad RightToLeft para cada control en el formulario por defecto se hereda,
por lo tanto, Panels y GroupBoxes siempre tienen la configuración RightToLeft necesaria.
Sin embargo, traté de reasignarlo para ellos, tanto de forma programática como de diseñador, no ayudó.

¿Fue útil?

Solución

Se ve que tienes un problema bastante desagradable en tus manos. Haber jugado con él por un tiempo y llegar a lo siguiente:

Utilizando un poco de recursión, puede ejecutar todos los controles y realizar la conversión de RTL de maná para los controles atrapados en Pannels y GroupBoxes.

Este es un pequeño simulacro de código rápido al que pegué. Le sugiero que coloque esto en su BaseForm (en este caso, con la esperanza de que tenga uno de estos) y solicite la carga del formulario base.

private void SetRTL (bool setRTL)
{
    ApplyRTL(setRTL, this);
}

private void ApplyRTL(bool yes, Control startControl)
{
    if ((startControl is Panel ) || (startControl is GroupBox))
    {
        foreach (Control control in startControl.Controls)
        {
            control.Location = CalculateRTL(control.Location, startControl.Size, control.Size);
        }
    }

    foreach (Control control in startControl.Controls)
        ApplyRTL(yes, control);
}

private Point CalculateRTL (Point currentPoint, Size parentSize, Size currentSize)
{
    return new Point(parentSize.Width - currentSize.Width - currentPoint.X, currentPoint.Y);
}

Otros consejos

No recuerdo dónde vi por primera vez este consejo sobre la anulación de CreateParams, pero aquí está;) La forma más rápida y sencilla es Heredar del Panel, GroupBox o Usercontrol y anular la propiedad CreateParams

    protected override CreateParams CreateParams
    {
        get
        {
            return Control_RTF(base.CreateParams, base.RightToLeft);
        }
    }

    private CreateParams Control_RTF(CreateParams CP, RightToLeft rightToLeft)
    {
        if (rightToLeft == System.Windows.Forms.RightToLeft.Yes)
            CP.ExStyle = ((CP.ExStyle | 0x400000) | 0x100000);
        return CP;
    }

Según el artículo Visual Studio 2005: Desarrollando aplicaciones de formularios árabes de Windows Solo me quedan dos alternativas

  • continuar agregando TableLayoutPanels aquí y allá
  • reposicionar controles secundarios en RTL cambiarme a mí mismo

Es una verdadera pena que tenga que ser así.

Si tiene una clase derivada de Control que contiene controles secundarios (como un ContainerControl ), puede agregar el siguiente código para forzar que todos los controles secundarios se reflejen cuando el RightToLeftLayout se establece en true y cuando el RightToLeft de su control se establece en RightToLeft.Yes .

protected override CreateParams CreateParams
{
    get
    {
        CreateParams createParams = base.CreateParams;
        Form parent = this.FindForm();
        bool parentRightToLeftLayout = parent != null ? parent.RightToLeftLayout : false;
        if ((this.RightToLeft == RightToLeft.Yes) && parentRightToLeftLayout)
        {
            createParams.ExStyle |= 0x500000; // WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT
            createParams.ExStyle &= ~0x7000; // WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR
        }
        return createParams;
    }
}

protected override void OnRightToLeftChanged(EventArgs e)
{
    base.OnRightToLeftChanged(e);
    RecreateHandle();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top