So aktualisieren Sie ein RichTextBox-Steuerelement aus der BackgroundWorker-Klasse mit BeginInvoke

Ich habe eine kleine app, die liest in einem Rohr delimted Datei und schreibt Zeilen in eine RTB, Hervorhebung, wenn es dissallowed Zeichen in bestimmte "Spalten". Das funktioniert perfekt...aber die Nutzer wollen einen Fortschrittsbalken und zu sehen, die Linien geschrieben wird, "live" und auch in der Lage sein, um abzubrechen, auf halbem Weg durch.

Habe ich folgende extension-Methode, die ich habe mit zu schreiben, auf eine RichTextBox ist, während die Blockierung der UI, aber dies fehlschlägt, mit einem BackgroundWorker mit BeginInvoke.

Fail ist, wenn Sie finden die aktuelle Länge des Textes.

public static void AppendLine(this RichTextBox richTextBox, string text, List<Char> foundChars, List<int> columns)
        {
            var split = text.Trim().Split(new char[] { '|' });

            for (int i = 0; i < split.Count(); i++)
            {
                **var start = richTextBox.TextLength;**
                richTextBox.AppendText(split[i]);
                var end = richTextBox.TextLength;

                if (columns.Contains(i + 1))
                {
                    foreach (var foundChar in foundChars)
                    {
                        var current = start;

                        while (current > 0)
                        {
                            var position = richTextBox.Find(new char[] { foundChar }, current, end);
                            current = position + 1;
                            if (current > 0)
                            {
                                richTextBox.Select(position, 1);
                                richTextBox.SelectionColor = Color.Red;
                            }
                        }
                    }
                }
                richTextBox.SelectionLength = 0;
                richTextBox.SelectionColor = Color.Black;
            }
            richTextBox.AppendLine();
        }

private void UpdateResultsLine(string line, List<char> foundChars)
        {
            if (txtResults.InvokeRequired)
            {
                txtResults.BeginInvoke(new UpdateResultsLineDelegate(UpdateResultsLine), line, foundChars);
            }
            txtResults.AppendLine(line, foundChars, _fileType.ProcessColumns);
        }

Jedoch, wenn ich rufe alle/all diese Erweiterungen in der gleichen Weise, die Sie arbeiten?

public static void AppendLine(this RichTextBox richTextBox)
{
    richTextBox.AppendText(Environment.NewLine);
}

public static void AppendLine(this RichTextBox richTextBox, string text)
{
    richTextBox.AppendText(text + Environment.NewLine);
}

public static void AppendLine(this RichTextBox richTextBox, string text, params object[] args)
{
    richTextBox.AppendLine(string.Format(text, args));
}

Was bin ich? oder gibt es einen anderen Weg zu schreiben, farbigen text in eine RTB?

  • Der Punkt mit der BackgroundWorker Komponente ist, dass Sie die Aktualisierung der Benutzeroberfläche in der ProgressChanged - und/oder RunWorkerCompleted event-handler-Methoden. Sie brauchen nicht zu verwenden BeginInvoke überhaupt. Siehe das Beispiel auf der MSDN-Website hier.
  • Sorry, aber nicht erfüllt voll meine Anforderungen. Ich brauche zu aktualisieren, mehr als eine RTB, plus wahrscheinlich ein label, und der Fortschrittsbalken. Ja, ich könnte ein neues Objekt erstellen, passieren rund, mit einem Enum zu sagen, was aktualisiert werden muss und wechseln in ProgressChanged-rufen, aber das scheint mir übertrieben.
  • Ich verstehe nicht, warum Sie nicht aktualisieren mehrerer Steuerelemente innerhalb der ProgressChanged event-handler-Methode. Sie nicht brauchen, um keine Objekte erstellen oder übergeben Sie herum. Der Punkt, der Umgang mit diesen Ereignissen ist, dass Sie sind aufgezogen auf dem UI-thread.
  • Mein BackgroundWorker ist dabei die Arbeit, so dass nur ER weiß, was geändert wurde, wo es bis zu, welche Datei er gerade bearbeitet. Es kann sagen, das UI zu aktualisieren...aber was hat das UI eigentlich schreiben, um die RTB-wenn BW nicht passieren, dass die Informationen zurück?
  • Auch beim aufrufen einer anderen richTextBox-Steuerelement.AppendText(...) funktioniert - und wenn in der Methode können Sie die TextLength-Eigenschaft...ich kann nicht sehen, warum das anders sein sollte?
  • BeginInvoke wird es auf der dispatcher-Warteschlange für die Benutzeroberfläche. Je nachdem, wie viel Arbeit Sie tun im hintergrund ist es vielleicht nicht bekommen, um für eine Weile tatsächlich die Aktualisierung der Benutzeroberfläche. Mit Invoke wird eine Synchronisierung erzwingen damit Ihre hintergrund-Arbeiter haben zu warten, bis die UI wurde aktualisiert. Also mit Invoke eher als BeginInvoke hat das Potenzial, zu verlangsamen Ihre eigentliche Arbeit, Handel es für eine regelmäßige Aktualisierung der Benutzeroberfläche.

InformationsquelleAutor BlueChippy | 2012-01-24
Schreibe einen Kommentar