Automatische Größenanpassung Textbox / RichTextBox

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Automatische Größenanpassung Textbox / RichTextBox

    Hi,

    Ich habe eine Form mit einer Textbox und der Multiline und WordWrap Eigenschaft True. Die Textbox ist mit "Anchor LEFT-UP-RIGHT-DOWN" an die Form gebunden.

    Da stelle ich per Programm TextStrings hinein, die sehr lang sein können.

    Es können Zeilenumbrüche aufgrund von überlangen Zeilen oder auch aufgrund von CrLf Vorschüben auftreten.

    Ich möchte nun immer die komplette Textbox sichtbar machen. Dazu möchte ich per Programm die Size der Form so anpassen, dass die TextBox komplett angezeigt wird.

    Um das tun zu können, muss ich natürlich wissen, wie hoch und breit der INHALT der Textbox ist.

    Den enthaltenen String kann ich ausmessen. Dann weiß ich wie lang und wie hoch der TextString ist und wie viele Zeilen es gibt.

    VB.NET-Quellcode

    1. Dim g As Graphics = RichTextBox1.CreateGraphics()
    2. Dim mySizeF As SizeF = g.MeasureString(RichTextBox1.Text, RichTextBox1.Font)
    3. Dim myCountLines As Integer = RichTextBox1.Lines.Count


    Damit wäre alles paletti ... wenn ...

    ... wenn es keine Zeilenumbrüche aufgrund überlanger Zeilen zu berücksichtigen gäbe. Denn mit myCountLines werden nur die CrLf Umbrüche gezählt ! Die anderen Ümbrüche kriege ich damit nicht zu fassen !

    Wie man am Coding sieht, habe ich inzwischen statt der TextBox eine RichTextBox verwendet ... denn da habe ich die Eigenschaft gefunden:

    VB.NET-Quellcode

    1. RichTextBox1.AutoSize = True


    Leider hilft mir das auch nicht weiter.

    Mist ! Ich bin wieder mal mit meinem Latein am Ende.

    Die Frage ist also, wie ich die tatsächliche Höhe des eingegebenen Textes ermitteln kann !

    Vielleicht gibt es ja eine ganz einfache Lösung. In diesem Fall wäre ich für eure nachsichtigen Ratschläge wie immer sehr dankbar .... :)

    LG
    Peter
    Leider nix konstruktives für den Anfang, aber: siehe Anhang

    ##########

    Allerdings: Wenn Du eine überlange Zeile ausmisst, kannst Du doch mit der RTB-Width ausrechnen, wieviele Zeilen das mit WordWrap entspricht. Und dann alle echte Zeilenhöhen addieren, um an die Sollhöhe zu kommen. Gibt aber bestimmt noch nen einfacheren Weg.
    Bilder
    • RtbAutoSize.png

      5,2 kB, 429×112, 6 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    @Peter329 In meinem Print-Verbrechen hab ich die Umkehrung exerziert:
    Drucken mehrseitiger Dokumente
    Vielleicht als Anhaltspunkt, ggf. rekursiv die richtigen Maße zu finden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Na ja, hinfummeln kann ich das natürlich ... ich kann den Textstring über einen Stringreader zeilenweise verarbeiten und schauen wie viele Display Zeilen die jeweiligen Textzeilen belegen und daraus die Datenhöhe berechnen.

    Aber mal ehrlich: das wundert mich schon, dass es da so ein Gefummel braucht ! Denn Microsoft kriegt das ja in ihrer MessageBox auch hin ! Oder müssen die auch so frickeln ?

    Notfalls bastle ich das Dingens eben so ... der Zweck heiligt die Mittel ... und Performance ist hier ja erfreulicherweise kein Thema ... :)

    LG
    Peter
    Was man nicht so alles auf stackoverflow findet:

    VB.NET-Quellcode

    1. Private Sub RichTextBox1_ContentsResized(sender As Object, e As ContentsResizedEventArgs) Handles RichTextBox1.ContentsResized
    2. RichTextBox1.Height = e.NewRectangle.Height + 5
    3. End Sub
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Man kann beim Ausmessen eines Textes auch ein LayoutRect angeben - wenn das eine bestimmte Breite hat ist das Ausmess-Ergebnis auch nicht breiter - also quasi misst er den Text aus unter Berücksichtigung der WordWrap-Zeilen.
    (ZB bei meinen Druck-Übungen habich immer ein LayoutRect in Breite des Papiers verwendet, aber unendliche Höhe. Die Messung ergab dann je nach Text eine bestimmte Höhe.
    So konnte ich dann sinnvoll die SeitenWechsel berechnen.)

    Die Form so breit machen wie den Text halte ich für ein gewagtes Unterfangen - es sind Texte denkbar, die dir dein Form-Layout dann wohl ziemlich zerschiessen können.

    VaporiZed schrieb:

    Was man nicht so alles auf stackoverflow findet:


    Na, du bist ja enorm findig ! :)

    Allerdings habe ich diese Lösung nicht umgesetzt. Denn ich will nicht noch ausgerechnet ein Event in die komplexe Rechnung mit hinein nehmen, das dann u.U. im dümmstmöglichen Moment feuern könnte ...

    Ich habe stattdessen wie von EDR vorgeschlagen die Signatur des g.MeasureString() mit der layoutarea verwendet.

    Allerdings scheinen mir die errechnete Width und Height trotz allem nicht so ganz richtig zu sein. Auch wenn die Abmessungen der RichTextBox noch etwas größer sind als die Maße, die für den String berechnet wurden, kommt beim Display der Daten es zu Zeilenüberläufen ! Eigentlich dürfte das dann ja nicht mehr auftreten !

    Na ja .. ich habe jetzt kräftig was "oben drauf geschlagen" und damit klappt die Sache. Eine reine Freude ist das Anpassen der Box mit dieser Methode allerdings nicht ... :)

    EDR hat natürlich vollkommen Recht, dass ich die maximale Breite der Box begrenzen muss ... aber das ist nur eine kleine Abfrage und schon ist die Sache erledigt.

    Danke für eure unendliche Geduld ... meine MessageBoxDark funktioniert nun ganz passabel .... und außerdem weiß ich jetzt, dass wenigstens in diesem Fall mein Problem nicht VOR dem Bildschirm gesessen hat ... :)

    Have a nice weekend ...
    LG
    Peter

    Peter329 schrieb:

    Allerdings scheinen mir die errechnete Width und Height trotz allem nicht so ganz richtig zu sein. Auch wenn die Abmessungen der RichTextBox noch etwas größer sind als die Maße, die für den String berechnet wurden, kommt beim Display der Daten es zu Zeilenüberläufen ! Eigentlich dürfte das dann ja nicht mehr auftreten !
    Jo, das ist auch so eine Wunderlichkeit: OwnerDrawing und MeasureString und Zeugs sind alle schön und gut, aber die .NetControls verwenden etwas, was TextRenderer heisst, und alles bisserl anners darstellt.
    Man kann iwie auch mit TextRenderer Texte ausmessen, aber wenn ich recht erinnere, macht das noch weniger Freude als die Graphics-Technologie.

    Aber vlt. machst du ja auch annere Fehler - zB bei MeasureString spielt auch das StringFormat eine Rolle - evtl. kannste damit ja deine Messung der Rtb-Darstellung weiter annähern.
    Evl. ists auch eine Idee, mit e.Graphics.DrawString Text-Darstellungen zu erzeugen, und mit der Darstellung der Rtb zu vergleichen.
    e.Graphics.DrawString ist glaub das genaue Pendant zu MeasureString, also wenn du da Einstellungen findest, die der Rtb-Darstellung gleichen, dann sind das auch die richtigen Messungs-Einstellungen.