Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update a RichTextBox from BackgroundWorker using BeginInvoke

I have a small app that reads in a pipe delimted file and writes out lines to a RTB, highlighting if there are dissallowed characters in certain "columns". This is working perfectly...however, the Users want a progress bar and to see the lines being written "live" and also to be able to cancel mid-way through.

I have the following extension method that I have been using to write to a RichTextBox, while blocking the UI, but this fails using a BackgroundWorker with BeginInvoke.

The fail is when finding the current length of the text.

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);
        }

However, if I call any/all of these extensions in the same way, they work?

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));
}

What am I missing? or is there another way to write coloured text to a RTB?

like image 943
BlueChippy Avatar asked Jan 23 '26 06:01

BlueChippy


1 Answers

Here what you can try, create the extension class as follows

public static class ControlExtensions
{
    public static void Invoke(this Control control, Action action)
    {
        if (control.InvokeRequired) control.Invoke(new MethodInvoker(action), null);
        else action.Invoke();
    }
 }

And when ever and where ever you want to update anything on UI, you just need to do

 richTextBox.Invoke(() => { richTextBox.AppendText(text + Environment.NewLine); });

Hope this works for you.

like image 145
Amar Palsapure Avatar answered Jan 25 '26 19:01

Amar Palsapure



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!