2010-05-23 16 views
14

In einem C# -Form habe ich ein Panel verankert alle Seiten, und im Inneren, ein Textfeld, verankert oben/links/rechts.Autoresize Textbox-Steuerelement vertikal

Wenn Text in das Textfeld geladen wird, möchte ich, dass er sich automatisch vertikal ausdehnt, so dass ich nicht durch das Textfeld blättern muss (höchstens durch das Fenster blättern, wenn mehr Text nicht in das Feld passt)). gibt es eine Möglichkeit, dies mit einem Textfeld zu tun? (Ich bin nicht gezwungen, dieses Steuerelement zu verwenden, wenn es ein anderes Steuerelement gibt, das der Beschreibung entspricht.)

Antwort

25

Ich nehme an, dies ist ein mehrzeiliges Textfeld, und Sie können es vertikal wachsen lassen. Dieser Code hat gut funktioniert:

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; 
    } 

Sie sollten vernünftig, etwas zu tun, wenn das Textfeld leer ist, wie die Eigenschaft MinimumSize- Einstellung.

+0

funktioniert wie ein Charm –

+0

Es funktioniert, aber nicht mit Zeilen ohne Leerzeichen. der eine, den David schrieb, handhabt das – docesam

+0

@Hans Passant Was ist, wenn es eine einzeilige Textbox ist? – 707

2

Sie können ein Label verwenden und AutoSize auf true setzen.

+1

ich denke, Autosize für horizontal ist. Liege ich falsch? –

0

Sie können es an der Unterseite verankern, die dafür sorgt, dass die Größe des Textfelds vertikal geändert wird, wenn das Format, zu dem es gehört, in der Größe geändert wird. Auch ein Textfeld, das seine Größe ändert, ist möglicherweise keine elegante Sache, da es die Darstellung anderer Komponenten stören könnte. Warum gibst du ihm keine maximale Größe, anstatt die Größe zu ändern?

2

Ich würde vorschlagen, Graphics.MeasureString zu verwenden.

Zuerst erstellen Sie ein Graphics Objekt, dann rufen Sie MeasureString darauf, übergeben Sie die Zeichenfolge und die Textbox Schriftart.

Beispiel

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; 
} 

Man könnte es auch nur die textBox.Size.Height Eigenschaft, indem auf die vertikale Achse begrenzen und mit Hilfe der MeasureString Überlastung, die int width akzeptiert auch.

bearbeiten

Wie SLaks erwähnt, ist eine weitere Option TextRenderer.MeasureString verwenden. Auf diese Weise muss kein Graphics Objekt erstellt werden.

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

Hier konnte man auf vertikale Größenanpassung begrenzen Hans-Technik, einen zusätzlichen Size Parameter MeasureString mit int.MaxValue Höhe vorbei.

+1

Sie haben vergessen, 'g' zu entsorgen. Sie sollten 'TextRenderer.MeasureString' aufrufen. – SLaks

25

Die aktuell gewählte keine Antwort auf Linien ohne Leerzeichen wie „jjjjjjjjjjjjjjjjjjjj“ x1000 Griff (darüber nachdenken, was passieren würde, wenn jemand eine URL eingefügt)

löst dieses Problem Dieser Code:

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

Dieser arbeitete wie Magie. – docesam

0

Versuchen Sie diesen Ansatz:

aspx.cs Code

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; 
} 

aspx Code

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