Risolto C# TextBox DockStyle.Fill posizionata in un panello centrale, va oltre ai bordi

Sevenjeak

Utente Gold
23 Settembre 2010
333
58
26
202
Salve,

E da molto che non scrivo su questo forum, inizio a riscrivere ponendovi questo problema, scusatemi in anticipo se il titolo è poco chiaro, non sapevo come altro intitolarla.

Nel mio form ho la necessita di creare dei componenti lato codice, un panello posizionato a top con tre panelli all'interno, uno a sinistra uno a centro e uno a destra, quello centrare ha al suo interno una textbox posizionata a fill, il codice è questo:

C#:
Panel bar = new Panel();

bar.Dock = DockStyle.Top;
bar.Height = 50;
bar.BackColor = Color.White;

Panel leftp = new Panel();
leftp.Dock = DockStyle.Left;
leftp.BackColor = Color.Yellow;
bar.Controls.Add(leftp);

Panel rightp = new Panel();
rightp.Dock = DockStyle.Right;
bar.Controls.Add(rightp);

Panel centerp = new Panel();
centerp.Dock = DockStyle.Fill;
centerp.BackColor = Color.Orange;
bar.Controls.Add(centerp);

TextBox txtB = new TextBox();
txtB.Dock = DockStyle.Fill;
centerp.Controls.Add(txtB);

Controls.Add(bar);

Eseguendo questo codice, ho notato un problema, ovvero, la textbox mi straborda, ovvero mi inizia e finisce prima di panello, posto il link ad un'immagine per farvi capire meglio:

https://ibb.co/hCXHB1F

Nell'immagine o inserito due frecce rosse per farvi capire meglio il mio problema, come potrei risolvere?
 
Usando DockStyle.Fill il panel centerp occuperà il form per tutta la sua larghezza, non lo vedi solo perché gli altri due panel sono sovrapposti e in primo piano, puoi verificare con centerp.BringToFront();

Ti consiglio di usare le ancore per questo layout, esempio 20-60-20 in percentuali:

1663710080719.png


C#:
        private Panel GeneratePanel(Color backColor, byte sizePercent, int left, AnchorStyles anchors)
        {
            int usableWidth = this.ClientRectangle.Width;
            int usableHeight = this.ClientRectangle.Height;
            int panelWidth = (int)Math.Floor(((double)sizePercent / 100) * usableWidth);
            return new Panel()
            {
                BackColor = backColor,
                Size = new Size(panelWidth, usableHeight),
                Left = left,
                Anchor = anchors
            };
        }

        private void GenerateLayout()
        {
            var baseAnchor = AnchorStyles.Top | AnchorStyles.Bottom;
            var leftPanel = GeneratePanel(Color.Yellow, 20, 0, baseAnchor | AnchorStyles.Left);
            var centerPanel = GeneratePanel(Color.Orange, 60, leftPanel.Width, baseAnchor | AnchorStyles.Left | AnchorStyles.Right);
            var rightPanel = GeneratePanel(Color.Navy, 20, leftPanel.Width + centerPanel.Width, baseAnchor | AnchorStyles.Right);
            var txtbox = new TextBox();
            txtbox.Dock = DockStyle.Top;
            centerPanel.Controls.Add(txtbox);

            this.Controls.Add(leftPanel);
            this.Controls.Add(centerPanel);
            this.Controls.Add(rightPanel);
        }

Non è il modo più pulito per farlo questo esempio è per dare un'idea; l'ideale sarebbe fare un componente ad hoc o almeno una classe che permette di gestire layout anche più variabili. Per com'è adesso, ridimensionando la finestra solo il pannello centrale verrà esteso, per mantenere le percentuali vanno tolte anche le ancore e va scritto del codice per gestire gli eventi di resize (deve calcolare nuovamente Width ed aggiornare Size e Location in tutti e tre i panel).
 
Ultima modifica:
Premetto che ancora non ho provato il tuo codice, mi sono soffermato alla funzione bringtofront(), ho notato che inserendo panelc.bringtofront(), prima di aggiungere il panello bar al form, il panello centrale non mi si sovrappone agli altri due, ma mi funziona come vorrei, senza usare il tuo codice con le percentuali.

In ogni caso, sto provando ora pure il tuo codice.

EDIT:

Ho appena provato il tuo codice e mi funzona, anche se ridimensiona la pagina, grazie per l'aiuto