Как заставить RightToLeftLayout работать для элементов управления внутри групповых блоков и панелей?

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

  •  02-07-2019
  •  | 
  •  

Вопрос

По данным MSDN

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

достаточно, чтобы отразить содержимое формы для языков с письмом справа налево.

Но размещение элементов управления зеркально отображается только для элементов управления, находящихся непосредственно в форме.
те, что внутри GroupBox или Panel не зеркально отражены, если я сначала не поместил их в TableLayoutPanel или FlowLayoutPanel.

Это много ручной работы по размещению таблетаута -панели внутри каждого группы Group Box, и особенно для перестройки управления (один контроль на таблицу, прокладку, маржу и т. Д.)

Есть ли более простой способ заставить зеркальное отображение работать для всех элементов управления?

Или, по крайней мере, как мне обойти этап перестановки, ведь с нашим количеством форм это довольно сложная задача?


Редактировать:Свойство 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, но здесь вы;) самый быстрый, и самый простой способ - унаследовать от панели, Groupbox или UserControl и переопределить свойство 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;
    }

Согласно статьеВизуальная Студия 2005:Разработка приложений Windows Forms на арабском языкеУ меня осталось только две альтернативы

  • продолжайте добавлять TableLayoutPanels здесь и там
  • самостоятельно изменить положение дочерних элементов управления при изменении RTL

Очень жаль, что так должно быть.

Если у вас есть класс, производный от Control, который содержит дочерние элементы управления (например, ContainerControl), вы можете добавить следующий код, чтобы заставить все дочерние элементы управления зеркально отражаться, когда родительская форма 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();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top