Come far funzionare RightToLeftLayout per i controlli all'interno di GroupBox e pannelli?

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

  •  02-07-2019
  •  | 
  •  

Domanda

Secondo MSDN

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

è sufficiente per mirrow il contenuto del modulo per le lingue RTL.

Ma il posizionamento dei controlli viene creato solo per i controlli immediatamente sul modulo,
quelli all'interno di un GroupBox o di un Pannello non sono specchiati , a meno che non li inserisca in un TableLayoutPanel o in un FlowLayoutPanel fisrt.

Questo è un sacco di lavoro manuale per posizionare un TableLayoutPanel all'interno di ogni GroupBox, e soprattutto per riorganizzare i controlli (un controllo per cella di tabella, riempimento, margine, ecc.)

C'è un modo più semplice per far funzionare il mirrowing per tutti i controlli?

O almeno, come posso evitare il passaggio di riorganizzazione, perché è piuttosto un compito con il nostro numero di moduli?


Modifica : la proprietà RightToLeft per ciascun controllo sul modulo per impostazione predefinita viene ereditata,
quindi i pannelli e le GroupBox hanno sempre l'impostazione RightToLeft necessaria.
Tuttavia, ho provato a riassegnarlo sia a livello di programmazione che da designer, non mi è stato di aiuto.

È stato utile?

Soluzione

Ha visto che hai un problema piuttosto brutto tra le mani. Ci ho giocato per un po 'e ho escogitato quanto segue:

Usando una piccola ricorsione puoi eseguire tutti i controlli ed eseguire la conversione manaul RTL per quei controlli intrappolati in Pannelli e GroupBox.

Questa è una rapida piccola derisione del codice che ho messo insieme. Ti suggerirei di metterlo nel tuo BaseForm (spera che tu abbia uno di questi) e chiamare il caricamento del modulo di 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);
}

Altri suggerimenti

Non ricordo dove ho visto per la prima volta questo suggerimento sulla sostituzione di CreateParams, ma eccoti qui;) il modo più rapido e semplice è Ereditare dal Pannello, GroupBox o Usercontrol e sovrascrivere la proprietà 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;
    }

Secondo l'articolo Visual Studio 2005: sviluppo di applicazioni arabe per Windows Form Mi restano solo due alternative

  • continua ad aggiungere TableLayoutPanels qua e là
  • riposiziona me stesso i controlli figlio su RTL

È un vero peccato che debba essere così.

Se hai una classe derivata da Control che contiene controlli figlio (come un ContainerControl ), puoi aggiungere il seguente codice per forzare il mirroring di tutti i controlli figlio quando RightToLeftLayout del modulo padre è impostato su true e quando RightToLeft del controllo è impostato su 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();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top