Como fazer o trabalho RightToLeftLayout para controles dentro GroupBoxes e painéis?

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

  •  02-07-2019
  •  | 
  •  

Pergunta

De acordo com MSDN

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

é o suficiente para mirrow o conteúdo do formulário para idiomas RTL.

colocação

Mas controles fica espelhadas somente para controles imediatamente no formulário,
aqueles dentro de um GroupBox ou por um painel não são espelhadas , a menos que eu colocá-los em um TableLayoutPanel ou um fisrt FlowLayoutPanel.

Este é um monte de trabalho manual para colocar um TableLayoutPanel dentro de cada GroupBox, e especialmente para reorganizar os controlos (controlo por uma célula da tabela, o preenchimento, a margem, etc)

Existe uma maneira mais fácil de fazer mirrowing trabalho para todos os controles?

Ou, pelo menos, como eu posso ignorar o passo rearranjando, pois é uma tarefa bastante com o nosso número de formas?


Editar : RightToLeft propriedade para cada controle no formulário por padrão é herdada,
assim Painéis e GroupBoxes sempre tem a configuração RightToLeft necessário.
No entanto, eu tentei de atribuí-lo para ambos programaticamente e do designer, isso não ajuda.

Foi útil?

Solução

Ele viu que você tem um problema bastante desagradável em suas mãos. Ter jogado com ele por um tempo e chegar com o seguinte:

Fazendo uso de um pouco de recursão você pode executar que todos os controles e fazer a conversão RTL manaul para esses controles presos em Painéis e GroupBoxes.

Esta é uma rápida pouco simulação de código que eu dei um tapa juntos. Eu sugiro que você colocar isso em seu BaseForm (heres esperando que você tem um desses) e chamada em carga formulário 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);
}

Outras dicas

Eu não me lembro onde eu vi pela primeira vez esta dica sobre substituindo CreateParams, mas você está aqui;) maneira mais rápida e mais fácil é para herdar a partir do Painel, GroupBox ou Usercontrol e substituir a propriedade 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;
    }

De acordo com o artigo Visual Studio 2005: Desenvolvimento de aplicações Windows Forms Árabe Eu fiquei com apenas duas alternativas

  • continuar adicionando TableLayoutPanels aqui e ali
  • controles de reposição criança em RTL me mudar

É uma pena que ele tem que ser assim.

Se você tem uma classe derivada de controle que contém controles filho (como um ContainerControl), você pode adicionar o seguinte código para forçar todos os controles filho de espelho quando RightToLeftLayout do formulário pai é definido como verdadeiro e quando RightToLeft do seu controle é conjunto para 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top