How to get RightToLeftLayout to work for controls inside GroupBoxes and panels?

According to MSDN

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

enough to mirror the contents of the form for RTL languages.

But placement control only becomes mirrored for controls immediately in the form,
those inside a GroupBox or Panel are not mirrored unless I put them in a TableLayoutPanel or FlowLayoutPanel fisrt.

This is a lot of manual work on placing a TableLayoutPanel inside each GroupBox, and especially for changing controls (one control per table cell, padding, edge, etc.)

Is there an easier way to do mirroring for all controls?

Or at least how can I get around the redistribution step, since it is a rather difficult task with our number of forms?


Edit : The RightToLeft property for each control is inherited by default,
therefore, panels and group boxes always have the necessary RightToLeft settings.
However, I tried to reassign it for them both programmatically and from the designer, it did not help.

+5
source share
4 answers

You can see that you have a rather unpleasant problem on your hands. Play with him for a while and come up with the following:

Using a little recursion, you can run all the controls and perform RTL conversion of the manual for these controls trapped in panels and group blocks.

This is a quick code layout that I hit together. I would advise you to put this in your BaseForm (in the hope that you have one of them) and call the base load.

 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); } 
+8
source

I don’t remember where I first saw this advice on redefining CreateParams, but here you are :) the fastest and easiest way is to inherit from Panel, GroupBox or Usercontrol and override the CreateParams property

  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; } 
+3
source

According to Visual Studio 2005 article : developing Windows Forms Arabic applications I was left with two alternatives

  • keep adding TableLayoutPanels here and there
  • Move child controls to RTL changes me

It is unfortunate that this should be so.

+1
source

If you have a class derived from a control that contains child controls (e.g. ContainerControl ), you can add the following code to make all child controls appear when the parent RightToLeftLayout form is set to true, and when your control RightToLeft set to 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(); } 
0
source

All Articles