GroupBox とパネル内のコントロールに対して RightToLeftLayout を機能させるにはどうすればよいですか?
-
02-07-2019 - |
質問
MSDN によると
form.RightToLeftLayout = True;
form.RightToLeft = ifWeWantRTL() ? RightToLeft.True : RightToLeft.False;
RTL 言語のフォーム コンテンツをミラーリングするには十分です。
ただし、コントロールの配置はフォーム上のコントロールに対してのみミラーリングされます。
GroupBox またはPanel 内のそれら ミラーリングされていません, 最初にそれらを TableLayoutPanel または FlowLayoutPanel に配置しない限り。
これは、各グループボックス内にTableLayOutPanelを配置し、特にコントロールを再配置するための多くの手動作業です(テーブルセル、パディング、マージンなど)コントロール(1つのコントロール)
すべてのコントロールに対してミラーリングを機能させる簡単な方法はありますか?
少なくとも、フォームの数が多いと再配置の手順が非常に大変なため、再配置の手順を回避するにはどうすればよいでしょうか?
編集:フォーム上の各コントロールの RightToLeft プロパティはデフォルトで継承されます。
したがって、パネルとグループボックスには常に必要な RightToLeft 設定があります。
それにもかかわらず、プログラムとデザイナーの両方でそれを再割り当てしようとしましたが、役に立ちませんでした。
解決
かなり厄介な問題を抱えていることがわかります。しばらく遊んでみて、次のことを思いつきました。
ちょっとした再帰を利用すると、すべてのコントロールを実行し、パンネルとグループボックスにトラップされたコントロールの手動 RTL 変換を行うことができます。
これは 素早い 私がまとめたコードの小さなモック。これを BaseForm に入れて (これらのいずれかがあることを願っています)、ベース フォームのロードを呼び出すことをお勧めします。
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);
}
他のヒント
CreateParamsのオーバーライドに関する最初のヒントを見た場所を覚えていませんが、ここにいます;) 最速かつ最も簡単な方法は、パネル、グループボックスまたはユーザーコントロールから継承することです 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;
}
記事によると Visual Studio 2005:アラビア語Windowsフォームアプリケーションの開発 選択肢は2つしかありません
- TableLayoutPanelのあちこちへの追加を続けます
- RTLの子コントロールの位置を変更すると自分自身が変更されます
そのようにしなければならないのは本当に残念です。
子コントロール( ContainerControl
など)を含むControlから派生したクラスがある場合、次のコードを追加して、親フォームの RightToLeftLayout
はtrueに設定され、コントロールの RightToLeft
が 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();
}