Langen String mit Zeilenumbruch versehen?

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von Tommel.

    Langen String mit Zeilenumbruch versehen?

    Hallo,

    also, ich habe google, und auch die Forum Suche benutzt, bin aber bei beidem nicht wirklich fündig geworden.
    Falls es doch ein Thema gibt, möchte ich mich für den Post quasie vorbeugend entschuldigen :)



    Zum Thema:

    Ich lese eine Liste aus einer Datenbank aus, und möchte diese Drucken.
    Klappt ganz gut, ich schreibe die einzelnen "rows" aus der Table mittels einer Schleife aufs Blatt, das ganze in Form einer Tabelle.
    Nun kann es aber sein, das ein bestimmtes feld aus zwei Worten besteht, oder aus 10Worten.
    Je nach dem muss ich also Zeilenumbrüche einfügen, da ich ja nur eine bestimmte Spaltenbreite zur verfügung habe.
    Damit das Sinn macht, sollte ich dem Wort nach trennen können, und zwar sollte dabei die Spaltenbreite beachtet werden.


    Versuche ich das über InstrRev und suche nach Leerzeichen, dann sägt er nach dem Letzten Wort ab.
    Das bringt mir dann nichts, weil ich immernoch breiter bin als die Breite die ich vorgesehen hab.

    Hat jemand einen Vorschlag?


    Falls ich das nicht... verständlich erklärt habe einfach sagen :D
    Ich hoffe ihr könnt mir helfen.

    mfg

    Thomas
    Also so ganz folgen kann ich dir zwar nicht, aber man erreicht in
    VB Zeilenbrüche mit hilfe von

    VB.NET-Quellcode

    1. vbNewLine

    beispiel :

    VB.NET-Quellcode

    1. textbox1.text = "Zeile1" + vbNewLine + "Zeile2"


    Ich hoffe du kannst damit etwas anfangen.

    mfg
    lexeaus
    Dachte ich mir schon. :)

    Dann so:

    Ich habe einen String:

    Dim String1 as String = "Hallo ich habe ein Problem"

    Ich möchte ihn mit einem Zeilenumbruch versehen, aber die stelle an der ich den Umbruch brauche ändert sich wenn sich der Text ändert. Manchmal reicht es ein Wort in der nächsten Zeile zu haben, manchmal müssen mehr worte in den Umbruch gelangen.
    Einen festen wert möchte ich nicht nehmen, das schaut blöd aus wenn das Wort abgeschnitten wird.

    Besser? :)

    PS: Ich weis wie ich einen Zeilenumbruch erreiche, aber nicht da wo ich ihn haben will. :(
    Hallo

    Hier ein Beispiel, das Du für Deine Zwecke umbauen kannst.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    3. Dim Zeilenlänge As Integer = 16
    4. Dim MeinText As String = "Hallo das ist ein Test, der bei einer Zeilenlänge von " & Zeilenlänge.ToString & " Zeichen, - aber nicht mitten in einem Wort einen Umbruch hinzufügt !"
    5. MeinText = Umbruch(MeinText, Zeilenlänge)
    6. If MeinText <> "" Then
    7. MsgBox(MeinText)
    8. End If
    9. End Sub
    10. Public Function Umbruch(ByVal Text As String, ByVal Zeilenlänge As Integer) As String
    11. Dim NeuerText As String = ""
    12. Dim Leerzeichen As Integer = 0
    13. Dim Worte() As String
    14. Dim Zahl As Integer = 0
    15. Worte = Text.Split(" ")
    16. For N As Integer = 0 To Worte.Length - 1
    17. If Worte(N).Length >= Zeilenlänge Then
    18. MsgBox("Die Zeilenlänge ist kleiner als die Wortlänge, bitte geben Sie eine größere Zeilenlänge ein.")
    19. Return ""
    20. End If
    21. Next
    22. For N As Integer = 0 To Text.Length - 1 Step Zeilenlänge
    23. Leerzeichen = 0
    24. If N + Zeilenlänge > Text.Length Then
    25. Zeilenlänge = Text.Length - N
    26. Zahl = 1
    27. End If
    28. Do While Not Text.Substring(N, Zeilenlänge + Leerzeichen).EndsWith(" ")
    29. Leerzeichen = Leerzeichen - 1
    30. Loop
    31. NeuerText = NeuerText & Text.Substring(N, Zeilenlänge + Leerzeichen + Zahl) & Constants.vbNewLine
    32. N = N + Leerzeichen
    33. Next
    34. Return NeuerText
    35. End Function
    36. End Class
    Hallo!

    @wincnc, danke für deinen Anstoss, der hat mir letzten endes geholfen!

    Ich habs allerdings etwas anders gelöst.
    Mir ist klar, dass diese Funktion nicht perfekt ist. Aber im Mom ausreichend *G*
    Ich häng sie hier mal an.

    Nochmals Danke an euch beide für die Hilfe!

    mfg

    Thomas.

    VB.NET-Quellcode

    1. Function zeilenumbruch(ByVal text As String, ByVal spalte As Single) As String
    2. 'Hier wird bestimmt wieviele Umbrüche eingefügt werden sollen
    3. Dim umbrüche As Decimal
    4. umbrüche = text.Length * 7.66 / spalte
    5. umbrüche = Math.Floor(umbrüche)Dim i As Integer = 0
    6. For i = 0 To text.Length - 1 ' Jedes zeichen durchgehen
    7. If text.Chars(i) = " " Then ' Sehen ob es ein Leerzeichen ist
    8. '7.66 etwa Breite eines Zeichens - Wenn es eins ist,
    9. 'sollte die Position nicht bereits hinter der Spaltenbreite liegen, aber auch nicht zu weit davor
    10. If i * 7.6 < spalte And i * 7.66 > spalte * 0.6 Then
    11. text = text.Remove(i, 1) 'Das Leerzeichen wegmachen
    12. text = text.Insert(i, Environment.NewLine) 'Umbruch einfügen
    13. umbrüche = umbrüche - 1
    14. End If
    15. If umbrüche = 0 Then
    16. Exit For
    17. End If
    18. End If
    19. Next
    20. Return text
    21. End Function
    hallo trommel,

    da du das ganze ja drucken willst, solltest du aber vom reinen zeichenzählen abkommen.
    warum ?

    ganz einfach:
    iiiiiiiiii brauchen weniger pixel als MMMMMMMMMM

    schau dir mal die MeasureString methode der graphics klasse an.

    beispiel:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    3. End Sub
    4. Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    5. Dim laengei As Integer = e.Graphics.MeasureString("iiiiiiiiii", Me.Font).Width
    6. Dim laengem As Integer = e.Graphics.MeasureString("MMMMMMMMMM", Me.Font).Width
    7. Stop
    8. End Sub
    9. End Class


    gruss

    mikeb69
    Du hast recht! Ich habe das aus faulheit so gemacht *schäm*, tatsächlich messe ich schonmal vorher den String um überhaupt zu entscheiden ob ich den Umbruch brauche. - Ist eine der Krücken die ich eingebaut habe. :whistling:

    Ich hab eben noch keine Idee wie ich die breite eines Teilstrings messen soll. Also IIIIMMMIIII <- Wie breit sind jetzt die M´s ..
    deswegen diese notlösung. Hab keine Lust das zu zerlegen und wieder zusammenzubauen usw.. Vil. gibts ne einfache Lösung
    und ich kenn sie halt noch nicht.....

    Hier noch der Codefetzen mit dem ich entscheide ob ich den umbruch brauche.

    gruß Thomas.

    VB.NET-Quellcode

    1. For s = 0 To 5
    2. strings(s) = Trim(strings(s))
    3. m_string(s) = g.MeasureString(strings(s), tb) 'Abmessen des Strings, um Umbruch zu bestimmen (wenn nötig)
    4. 'Hier gleich entscheiden ob das Ding zu breit für eine Spalte ist
    5. If m_string(s).Width > b(s) Then
    6. hd = True
    7. strings(s) = Me.zeilenumbruch(strings(s), b(s))
    8. End If
    9. Next
    wie wärs damit, wenn du immer so lange Buchstaben zu deinem String für die hinzufügst, bis es die maximale Größe überschreitet, und dann ziehst du noch alle Buchstaben bis zum nächsten Leerzeichen wieder ab? So dürfte es dir helfen...
    Hallo Lupus,

    ich bin mir nicht ganz sicher wie du das meinst. Ich soll den String einzeln mit Buchstaben bestücken, also nicht gleich den ganzen Satz reindonnern, sondern Tröpchenweise die Buchstaben, und nebenher immer beobachten
    ob ich die Spaltenbreite überschritten habe. So meinst du das oder?

    mfg

    Thomas.
    hallo trommel,

    vor einiger zeit hab ich mir mal eine rekursive funktion geschrieben die genau das macht.
    jedoch nicht buchstabe für buchstabe sonder wort für wort.

    muss mal schauen wo ich die habe.

    gruss

    mikeb69
    damit mein ich wenn du jetzt z.b. den Satz hast:
    Die Sonne steht heute Mittag hoch am Himmel.
    Und der ist zu lang für deine Zeile, misst du erst die Länge vom ersten Buchstabe, oder vom ersten Wort (besser), also von "Die". Wenn das Wort noch zu kurz ist, bringst du das nächste Wort dazu: "Die Sonne", und so weiter. Sobald der Text länger als die maximale Länge ist, nimmst du das letzte Wort wieder weg und dann hast du deine Trennung
    hallo,

    wer das selbst machen will, soll einfach mal wegsehen.
    hier eine vorstellbare lösung.
    der text wird mit entsprechend vielen zeilenumbrüchen versehen, sodass er immer in die form passt.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private t As String = "Dies ist mein Superlanger Text, der an der richtigen Stellen mit Zeilenumbrüchen versehen werden soll."
    3. ''' <summary>Fügt Zeilenumbrüche in den Text ein, sodass er immer im Zeichenbereich dargestellt werden kann.</summary>
    4. ''' <param name="t">Text der dargestellt werden soll.</param>
    5. ''' <param name="s">Größe des verfügbaren Zeichenbereiches.</param>
    6. ''' <param name="f">Verwendeter Font.</param>
    7. ''' <param name="pos">Aktuelle Position an der ein Zeilenumbruch möglich ist. Optional, da beim ersten Aufruf nicht nötig ist.</param>
    8. ''' <param name="lastpos">Letzte geprüfte Position. Optional, da beim ersten Aufruf nicht nötig ist.</param>
    9. ''' <returns>Text mit Zeilenumbrüchen.</returns>
    10. ''' <remarks>Der String wird nur in der Länge Formatiert. Ein prüfen in der Höhe findet nicht statt.</remarks>
    11. Private Function FitString2Bitmap(ByVal t As String, ByVal s As Size, ByVal f As Font, Optional ByVal pos As Integer = 0, Optional ByVal lastpos As Integer = 0) As String
    12. Dim temppos As Integer = t.IndexOf(" ", pos)
    13. If temppos = -1 Then
    14. Return t
    15. Else
    16. Dim b As New Bitmap(s.Width, s.Height)
    17. Using g As Graphics = Graphics.FromImage(b)
    18. Dim stringsize As SizeF = g.MeasureString(t.Substring(0, temppos), f)
    19. If s.Width > stringsize.Width Then
    20. 'string ist noch ok
    21. Return FitString2Bitmap(t, s, f, temppos + 1, temppos)
    22. Else
    23. 'string ist zu lang
    24. Dim temp As String = t.Substring(0, pos - 1) & Environment.NewLine & t.Substring(pos)
    25. Return FitString2Bitmap(temp, s, f, pos + 1, pos)
    26. End If
    27. End Using
    28. End If
    29. End Function
    30. Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    31. e.Graphics.DrawString(FitString2Bitmap(t, Me.ClientSize, Me.Font), Me.Font, Brushes.Black, 0, Me.Height / 2)
    32. End Sub
    33. Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
    34. Me.Refresh()
    35. End Sub
    36. End Class


    EDIT: Kommentare eingefügt

    gruss

    mikeb69

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

    Servus!
    Puh so viel Aufmerksamkeit :) danke für den Code, ich werde die kommenden Tage hier Posten wie ich das Problem gelöst habe. (Sicher mit deiner Lösung, oder nahe daran).

    Ich möchte mich mal für die Hilfe hier bedanken, ganz dickes Küü.. ää Dankeschön :thumbsup:

    Wenn ich den Umbruch überarbeitet habe Poste iches nochmal hier herein.


    grüße

    Thomas.