Laden...

Nach x Zeichen autom. Zeilenumbruch in Multiline-Textbox jedoch Wörter nicht trennen

Erstellt von theSoulT vor 5 Jahren Letzter Beitrag vor 5 Jahren 2.608 Views
T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 5 Jahren
Nach x Zeichen autom. Zeilenumbruch in Multiline-Textbox jedoch Wörter nicht trennen

Hallo zusammen,

ich benötige mal wieder eure Hilfe,
ich komme einfach nicht weiter. Für ein Projekt benötige ich einen automatischen Zeilenumbruch. Das heißt ich schreibe in einer Multiline-TextBox meinen Text. Es sollen in jeder Zeile maximal 72 Zeichen stehen. Das heißt wenn ein Wort bei 70 anfängt und über 72 geht soll das ganze Wort in die nächste Zeile geschrieben werden. Leider bekomme ich das nicht hin. Habt ihr da einen Ansatz? Oder gibt es für TextBoxen schon Einstellungsmöglichkeiten für die maximale Anzahl pro Zeile?

16.807 Beiträge seit 2008
vor 5 Jahren

Was hast denn bisher probiert?
Im Prinzip hast ja den Ansatz schon selbst erklärt; musst ihn halt nur in Code gießen.

T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 5 Jahren

Mein Problem ist folgendes:
ich müsste Zeile für Zeile kontrollieren, ob mehr als 72 Zeichen stehen. Wenn ja dann sollen alle worte über 72 in die nächste Zeile geschrieben werden.

Ich hätte das jetzt mit foreach(string lines in TextBox1.Lines) gemacht.
Allerdings ist hier das Problem das ich dann lines nichts zuweisen kann.

            
 private void textBox1_TextChanged(object sender, EventArgs e)
        {
         foreach (string lines in textBox1.Lines)
            {
                string[] zeile = lines.Split();
                char[] buchstaben = lines.ToCharArray();
                int count = 0;
                int lastWord = 0;

                if (buchstaben.Length > maxCount)
                {
                    for (int i = 0; i < zeile.Length; i++)
                    {
                        if (count < maxCount)
                        {
                            count += zeile[i].Length;
                        }
                        else
                        {
                            lastWord = i;
                            break;
                        }
                    }
                    for(int i = 0; i < lastWord; i++)
                    {
                        gesamttext += zeile[i] + " ";
                    }
                    gesamttext += Environment.NewLine;
                    for(int i = lastWord; i < zeile.Length; i++)
                    {
                        gesamttext += zeile[i] + " ";
                    }
                    textBox1.Text = gesamttext;
                }
            }
        }

Das hier ist mein aktueller Versuch, aber das klappt leider auch nicht so ganz 😦

16.807 Beiträge seit 2008
vor 5 Jahren

Der Code passt auch nicht zu Deinem gesagten.

Wenn Du Deine Aufgabe nicht klar verstehst, dann mal diese zunächst Schrittweise auf ein Papier auf - und dann programmiere Stück für Stück die einzelnen Schritte aus.

Genau das hab ich jetzt einfach mal gemacht:

        static void Main(string[] args)
        {

            string text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";

            string blockformat = TextExtensions.Blockformat(text, 72);

            Console.WriteLine(blockformat);

            Console.ReadKey();
        }

        public static class TextExtensions
        {
            public static string Blockformat(string source, int maxCharsPerLine)
            {
                string input = source;
                string result = "";

                while (input != "")
                {
                    // trim line
                    string subText = input.Substring(0, Math.Min(maxCharsPerLine, input.Length)).Trim();

                    // letzter space im text suchen
                    int lastSpacePosition = subText.LastIndexOf(" ");


                    if (lastSpacePosition == -1)
                    {
                        // kein space enthalten
                        result += subText + Environment.NewLine;
                    }
                    else
                    {
                        // space gefunden

                        // subtext trimmen
                        subText = input.Substring(0, lastSpacePosition + 1);

                        // subtext in das result kippen
                        result += subText + Environment.NewLine;

                    }

                    // input um subtext verringern
                    input = input.Substring(subText.Length);
                }

                return result;
            }
        }

Das macht im Endeffekt genau das in der Form, wie Du es beschrieben hast - anders als Dein Code, der eben nicht zur Beschreibung passt.

Ich bin sicher, dass mein Code nicht jeden potentiellen Fall abdeckt; aber er zeigt minimalst, dass man einfach genau das ausprogrammieren muss, was man selbst beschreibt.

T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 5 Jahren

Servus und danke erstmal für deinen Vorschlag.
Das Problem ist nur das es in jeder Zeile überprüft werden soll. Und damit hab ich meine Probleme 😭

16.807 Beiträge seit 2008
vor 5 Jahren

Ich werde Dir jetzt nicht den perfekten Code schreiben... dazu ist das Forum nicht da.
Nen bisschen musst auch selbst machen; die Basis hast 😉

Im Endeffekt musst Du ja nur noch iterieren...

T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 5 Jahren

Hab es hinbekommen. Danke für deinen Ansatz!
Hier noch mein Code, falls jemand anderes noch die selben Probleme hat:

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (counter == 0)
                Blockformat(textBox1, 40);
        }
        public void Blockformat(TextBox source, int maxCharsPerLine)
        {
            string gesamttext = source.Text;
            string zeile = "";
            int lastSpace;
            List<string> satz = new List<string>();

            counter = 1;
            if (gesamttext.Length >= maxCharsPerLine)
            {
                while (gesamttext.Length > 0)
                {
                    int min = Math.Min(gesamttext.Length, maxCharsPerLine);
                    zeile = gesamttext.Substring(0, min);
                    lastSpace = zeile.LastIndexOf(" ") + 1;

                    if (lastSpace > 0)
                    {
                        if (gesamttext.Length > maxCharsPerLine)
                        {
                            zeile = gesamttext.Substring(0, lastSpace);
                            gesamttext = gesamttext.Substring(lastSpace).Replace(Environment.NewLine, "");
                        }
                        else
                            gesamttext = "";
                        satz.Add(zeile);
                    }
                    else
                    {
                        zeile = gesamttext.Substring(0, min);
                        if (zeile != "")
                            satz.Add(zeile);
                        gesamttext = gesamttext.Substring(min).Replace(Environment.NewLine, "");
                    }
                }
                source.Text = "";
                foreach (string s in satz)
                {
                    source.Text += s + Environment.NewLine;
                }
                source.Text = source.Text.Substring(0, source.Text.Length - Environment.NewLine.Length);
                source.SelectionStart = source.Text.Length;
                source.ScrollToCaret();
            }

            counter = 0;
        }
16.807 Beiträge seit 2008
vor 5 Jahren

Beachte die Schichtentrennung.
[Artikel] Drei-Schichten-Architektur

Im Sinne der Wiederverwendbar- und Testbakeit ist es besser, wenn Deine Methode keine Abhängigkeit an die UI und damit keine Abhängigkeit an die Textbox hätte; sondern wie meine Vorlage einen String annimmt und einen zurück gibt.

Zudem scheinst Du mir irgendwelchen Feldern zu arbeiten, was hier eher ein Risiko darstellt.

T
theSoulT Themenstarter:in
64 Beiträge seit 2018
vor 5 Jahren

Im Sinne der Wiederverwendbar- und Testbakeit ist es besser, wenn Deine Methode keine Abhängigkeit an die UI und damit keine Abhängigkeit an die Textbox hätte; sondern wie meine Vorlage einen String annimmt und einen zurück gibt.

Du hast recht, das muss ich noch anpassen. Danke dir!