Como fazer o trabalho RightToLeftLayout para controles dentro GroupBoxes e painéis?
-
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.
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();
}