2010-05-23 12 views
14

In un formato C#, ho un pannello ancorato su tutti i lati e all'interno, una casella di testo, ancorata in alto/a sinistra/a destra.Autoresize controllo casella di testo verticalmente

Quando il testo viene caricato nella casella di testo, voglio che si espanda automaticamente verticalmente in modo che non sia necessario scorrere la casella di testo (far scorrere il pannello al massimo, se c'è più testo che non si adatta al pannello). c'è un modo per farlo con una casella di testo? (Non sono vincolato a utilizzare questo controllo, quindi se c'è un altro controllo che si adatta alla descrizione, sentitevi liberi di menzionarlo)

risposta

25

Suppongo che questa sia una casella di testo su più righe e che le consentiate di crescere verticalmente. Questo codice ha funzionato bene:

private void textBox1_TextChanged(object sender, EventArgs e) { 
     Size sz = new Size(textBox1.ClientSize.Width, int.MaxValue); 
     TextFormatFlags flags = TextFormatFlags.WordBreak; 
     int padding = 3; 
     int borders = textBox1.Height - textBox1.ClientSize.Height; 
     sz = TextRenderer.MeasureText(textBox1.Text, textBox1.Font, sz, flags); 
     int h = sz.Height + borders + padding; 
     if (textBox1.Top + h > this.ClientSize.Height - 10) { 
      h = this.ClientSize.Height - 10 - textBox1.Top; 
     } 
     textBox1.Height = h; 
    } 

Si dovrebbe fare qualcosa di ragionevole quando la casella di testo è vuota, come l'impostazione della proprietà MinimumSize.

+0

funziona come un fascino –

+0

Funziona ma non gestisce le linee senza spazi. quello che David ha scritto gestisce che – docesam

+0

@Hans Passant Cosa succede se si tratta di una casella di testo a riga singola? – 707

2

È possibile utilizzare un'etichetta e impostare AutoSize su true.

+1

credo autosize è per orizzontale. ho sbagliato? –

0

È possibile ancorarlo in fondo, per garantire che la casella di testo venga ridimensionata verticalmente quando la forma a cui appartiene viene ridimensionata. Inoltre, una casella di testo che cambia le sue dimensioni potrebbe non essere una cosa elegante in quanto potrebbe interrompere il modo in cui vengono visualizzati gli altri componenti. Perché non le dai la dimensione massima invece di ridimensionarla?

2

Suggerirei di utilizzare Graphics.MeasureString.

Prima di creare un oggetto Graphics, quindi chiamare MeasureString su di esso, passando la stringa e il carattere della casella di testo.

Esempio

string text = "TestingTesting\nTestingTesting\nTestingTesting\nTestingTesting\n"; 

// Create the graphics object. 
using (Graphics g = textBox.CreateGraphics()) {   
    // Set the control's size to the string's size. 
    textBox.Size = g.MeasureString(text, textBox.Font).ToSize(); 
    textBox.Text = text; 
} 

Si potrebbe anche limitare all'asse verticale impostando solo la proprietà textBox.Size.Height e utilizzando la MeasureString sovraccarico che accetta anche int width.

Modifica

Come SLaks sottolineato, un'altra opzione sta usando TextRenderer.MeasureString. In questo modo non è necessario creare un oggetto Graphics.

textBox.Size = TextRenderer.MeasureString(text, textBox.Font).ToSize(); 

Qui si potrebbe limitare a ridimensionamento verticale utilizzando la tecnica di Hans', passando un parametro aggiuntivo Size-MeasureString con int.MaxValue altezza.

+1

Hai dimenticato di gettare 'g'. Dovresti chiamare 'TextRenderer.MeasureString'. – SLaks

25

L'attuale risposta selezionata non gestisce le linee senza spazi come x1000 "jjjjjjjjjjjjjjjjjjjj" (pensare a cosa sarebbe successo se qualcuno incollato un URL)

Questo codice risolve questo problema:

private void txtBody_TextChanged(object sender, EventArgs e) 
{ 
    // amount of padding to add 
    const int padding = 3; 
    // get number of lines (first line is 0, so add 1) 
    int numLines = this.txtBody.GetLineFromCharIndex(this.txtBody.TextLength) + 1; 
    // get border thickness 
    int border = this.txtBody.Height - this.txtBody.ClientSize.Height; 
    // set height (height of one line * number of lines + spacing) 
    this.txtBody.Height = this.txtBody.Font.Height * numLines + padding + border; 
} 
+0

Questo ha funzionato come per magia. – docesam

0

Prova questo approccio:

aspx.codice cs

protected int GetRows(object value) { 
     if (value == null || string.IsNullOrWhiteSpace(value.ToString())) 
      return 1; 

     var contentTrimmed = value.ToString().Replace('\t', ' ').Replace('\r', ' ').Replace('\n', ' ').Trim(); 

     var length = (decimal)contentTrimmed.Length; 
     if (length == 0) 
      return 1; 

     int res = 0; 
     decimal maxLength = 56; 
     using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(new Bitmap(1, 1))) 
     { 
      SizeF sizeRef = graphics.MeasureString("W", new Font("Segoe UI", 13, FontStyle.Regular, GraphicsUnit.Pixel)); 
      maxLength = maxLength * (decimal)sizeRef.Width; 

      SizeF size = graphics.MeasureString(contentTrimmed, new Font("Segoe UI", 13, FontStyle.Regular, GraphicsUnit.Pixel)); 
      length = (decimal)size.Width; 
     } 

     res = (int)Math.Round(length/(decimal)maxLength, MidpointRounding.AwayFromZero); 
     if (res == 0) 
      return 1; 

     return res; 
} 

codice aspx

<asp:TextBox ID="txtValue" TextMode="MultiLine" Text='<%# Eval("Value") %>' runat="server" MaxLength="500" Width="700px" Rows='<%# GetRows(Eval ("Value")) %>' ></asp:TextBox> 
Problemi correlati