Ich habe hier folgenden Bestandteil einer Form:
private void textBox1_TextChanged(object sender, EventArgs e)
{
SizeF size = this.CreateGraphics().MeasureString(textBox1.Text, textBox1.Font);
// Höhe und Breite erfassen
int width = (int)size.Width;
int height = (int)size.Height;
// Anpassen an MaximumSize
if (width > textBox1.MaximumSize.Width) width = textBox1.MaximumSize.Width;
if (height > textBox1.MaximumSize.Height) height = textBox1.MaximumSize.Height;
// Anpassen an MinimumSize
if (width < textBox1.MinimumSize.Width) width = textBox1.MinimumSize.Width;
if (height < textBox1.MinimumSize.Height) height = textBox1.MinimumSize.Height;
// Neue Größe speichern
this.textBox1.Width = width;
this.textBox1.Height = height;
}
Und diese Eigenschaften:
this.textBox1.WordWrap = true;
this.textBox1.Multiline = true;
this.textBox1.Margin = new Padding(0);
this.textBox1.MaximumSize = new Size(600, 1000);
this.FormBorderStyle = FormBorderStyle.None;
Das soll bewirken, dass die TextBox sich automatisch an seinen Inhalt anpasst, aber noch im Rahmen der Maximal- und Minimal-Vorgaben bleibt.
Wenn ich das nun starte, funktioniert das mit der Breite auch wunderbar, bis die maximale Breite erreicht ist, aber dann wird keine neue Zeile begonnen.
Zumindest sehe ich das nicht, weil die TextBox sich nicht nach unten aus dehnt.
Ich denke, das liegt daran, dass in "size" die Breite und Höhe des Textes angegeben wird, aber wenn der Text immer auf einer Zeile liegt, wird auch immer die Höhe gleich bleiben.
Habs mit "textBox1.Lines.Length" aber da bleibt die Anzahl Zeilen ja auch gleich.
Hat jemand eine Idee, wie ich es hin bekommen kann, dass sich der TextBox immer eine Zeile anfügt, wenn der Text zu lang für die vorherige wird?
Oder muss ich da mit der RichTextBox arbeiten?
NuGet Packages im Code auslesen
lock Alternative für async/await
Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.
Du kannst der MeasureString-Methode noch die maximale Breite als 3. Parameter angeben.
Super, funktioniert^^
Danke 😃
NuGet Packages im Code auslesen
lock Alternative für async/await
Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.
Hi Zusammen
Ich habe ein kleines Problem zum selben Thema. Vielleicht kann einer von euch mir helfen, auch wenn das Thema vom letzten Jahr ist.
Ausgangspunt ist, das ich gewisse Multiline-Textboxen auf einer Form habe, die leider nicht sehr viel Platz haben, weil die Form nur von Steuerelementen überladen ist (typisch Kunde: am besten alles auf einen Blick ^^)
Um jetzt den gesamten Text der Textbox anzeigen zu können, soll sich die Größe der Textbox an dessen Inhalt anpassen, sobald der Fokus auf dieser Textbox liegt. Dabei soll jedoch die Breite der Textbox unverändert bleiben und nur die Höhe angepast werden. Eine MaximumSize gibt es nicht. Nur die MinimumSize, die der Größe er Textbox im nichtfokusiierten Zustand entspricht. (Diesen Wert speichere ich beim laden der Form jeweils im Tag der Textbox)
Gebe ich nun Text ein, erweitert sich diese auch schön brav um die Zeilen. Verlasse ich die Textbox geht sie in den Ausgangzustand zurück. Jedoch ist mir beim Testen etwas aufgefallen. Nach mehrerem Einfügen von Absätzen passiert es ab und zu das sich die Höhe des Textfeldes nicht ändert sondern die oberste Zeile hochgeschoben wird, sodass man sie nicht sieht. Das ist ja eigentlich unerwünscht, da man den gesamten Text sehen möchte, soweit es die Größe des Bildschirmes zulässt.
Woran liegt das? Kann man das eventuell verhindern?
LG
private void txt_changed(object sender, EventArgs e)
{
//Größe eventuell aktualisieren
if ((pan_doc.Controls.Contains(sender as TextBox)) && (sender as TextBox).Focused)
createNewSize(sender);
}
private void textbox_Enter(object sender, EventArgs e)
{
//Control hat focus -> Größe der Textbox an Text anpassen
if ((pan_doc.Controls.Contains(sender as TextBox)) && (sender as TextBox).Focused)
{
//Berechnen der neuen Größe
createNewSize(sender);
}
}
private void createNewSize(object sender)
{
SizeF test = this.CreateGraphics().MeasureString((sender as TextBox).Text,
(sender as TextBox).Font, (sender as TextBox).Size.Width);
(sender as TextBox).Height = (int)test.Height + 1;
(sender as TextBox).BringToFront();
}
private void Textbox_Leave(object sender, EventArgs e)
{
if (pan_doc.Controls.Contains(sender as TextBox))
{//Größe zurücksetzen
(sender as TextBox).Size = (Size)(sender as TextBox).Tag;
}
}
Hallo LearningGirl,
ich würde es als erstes mal mit Width-x bei MeasureString probieren, wobei x empirisch zu ermitteln wäre.
herbivore
Guten Morgen herbivore,
danke für die schnelle Antwort. Ich verstehe nur gerade nicht, was du mit deiner Aussage andeuten willst. Was meinst du mit diesem x?
LG
Hallo LearningGirl,
ich ich schon sagte, wäre x ein Wert (eine Konstante), den man empirisch ermitteln müsste. Beginne bei 1, und erhöhe jedes Mal um 1, sollte der Fehler noch auftreten.
herbivore
Offtopic:
Du kannst den Speicherbedarf noch optimieren.... wenn Du das Graphics nach Verwendung disposed...
using (Graphics g=this.CreateGraphics(.......)
{
}
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
@herbivore
Jetzt verstehe ich... werde mich gleich mal an die Arbeit machen.
@Programmierhans
Danke für den Tipp 😉
Also ich hatte nun etwas experimentiert mit dem wisth - x. Jedoch hat das nicht verbessert.
Außerdem ist mir aufgefallen dass die Methode anscheinend die Absätze (\r\n) nicht richtig interpretiert. steht der Absatz als letztes da, schiebt er den text immer außer Sicht. Steht dahinter ein Text, interpretiert er es richtig, aber nur wenn es unmittelbar dahinter steht. bei mehreren Zeilen scheint er aber auch ab und zu eine Außnahme zu machen...
Beispiel:
ich kürze jeden Absatz (\r\n) mal mit einem * ab
Text -> Ergebnis
[...]** -> Fehlt 1 Zeile
[...]* -> Fehlt 1
[...]f -> richtig dargestellt
[...]f -> Fehlt 1
[...]fm -> richtig
[...]fm -> Fehlt 1
[...]fm** -> Fehlt 1
[...]fmg -> richtig
[...]fmg* -> Fehlt 1
[...]fmg -> Fehlt 1
[...]fmg* -> Fehlt 1
[...]fmgm -> richtig
[...]fmgm-> Fehlt 1
[...]fmgm-> Fehlt 1
[...]fmgm-> Fehlt 2
[...]fmgm**m-> Fehlt 1
usw.
Mal fehlt unten eine Zeile, mal schiebt er den Text nach oben.
Hallo LearningGirl,
übergib mal Regex.Replace (textBox1.Text, @"[\r\n]+$", "\r\n.")
an MeasureString. Das sollte das Problem bis auf den Fall "Fehlt 2" lösen. Der lässt sich aber vielleicht durch meinen ersten Vorschlag beheben.
herbivore
Hi herbivore,
danke für deine Hilfe. Bei den ersten Versuchen haben sich Verbesserungen gezeigt, jedoch keine vollständige Lösung.
So ergab sich für die gleichen Tests wie oben folgende Verbesserungen.
[...]** -> Fehlt 1 Zeile
[...]* -> jetzt richtig
[...]f -> richtig
[...]f -> jetzt richtig
[...]fm -> richtig
[...]fm -> jetzt richtig
[...]fm** -> Fehlt 1
[...]fmg -> richtig
[...]fmg* -> jetzt richtig
[...]fmg -> Fehlt 1
[...]fmg* -> jetzt Fehlt 2
[...]fmgm -> richtig
[...]fmgm-> jetzt richtig
[...]fmgm-> Fehlt 1
[...]fmgm-> Fehlt 2
[...]fmgm**m-> Fehlt 1
Wenn ich jedoch zum Beispiel nur Absätze einfüge, ohne Text dazwischen, dann schiebt er den Text bei jedem neuen Absatz eine Zeile weiter hoch und die Textbox nimmt an Höhe nicht zu. Erst wenn man dann ein Zecihen einfügt, korigiert er die Höhe mit einem Schub. Dabei fehlt ab und zu jedoch wieder eine Zeile.
Die ersten Tests mit width - x waren auch nicht erfolgreicher.
LG
Hallo LearningGirl,
du solltest mal textBox.ClientSize.Width verwenden (daher auch der Vorschlag von herbivore bzgl. "-x").
Und dann schau dir mal die Überladung von MeasureString() mittels StringFormat an und probiere mal verschiedene Einstellungen durch, besonders die FormatFlags.
Notfalls würde ich einfach die TextBox in der Höhe ein bißchen größer machen, damit der Text immer reinpaßt.
Hi Th69,
ich habe eben eine andere Variante mal versucht und die sieht sehr vielversprechend aus. Die Höhe scheint immer den richtigen Wert zu haben. Nur ab und zu ist beim Aktualisieren der Höhe ein Flackern zu verzeichnen, wenn man zu schnell zu viel verändert:
private void createNewSize(object sender)
{
Size sz = new Size((sender as TextBox).ClientSize.Width, int.MaxValue);
TextFormatFlags flags = TextFormatFlags.WordBreak;
int padding = 3;
int borders = (sender as TextBox).Height - (sender as TextBox).ClientSize.Height;
sz = TextRenderer.MeasureText((sender as TextBox).Text, (sender as TextBox).Font, sz, flags);
int h = sz.Height + borders + padding;
if ((sender as TextBox).Top + h > this.ClientSize.Height - 10)
{
h = this.ClientSize.Height - 10 - (sender as TextBox).Top;
}
(sender as TextBox).Height = h;
(sender as TextBox).BringToFront();
}