如何使用BeginInvoke从BackgroundWorker更新RichTextBox

本文关键字:更新 RichTextBox BackgroundWorker 何使用 BeginInvoke | 更新日期: 2023-09-27 18:21:09

我有一个小应用程序,它读取管道提交的文件,并向RTB写入行,突出显示某些"列"中是否存在不允许的字符。这是完美的工作。。。然而,用户想要一个进度条,可以看到正在"实时"写入的行,也可以中途取消。

我有以下扩展方法,在阻塞UI时,我一直在使用它来写入RichTextBox,但使用带有BeginInvoke的BackgroundWorker失败了。

失败是在查找文本的当前长度时。

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

但是,如果我以相同的方式调用这些扩展中的任何一个/全部,它们是否有效?

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

我错过了什么?或者有没有其他方法可以将彩色文本写入RTB?

如何使用BeginInvoke从BackgroundWorker更新RichTextBox

在这里,您可以尝试如下创建扩展类

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

无论何时何地,你都想更新UI上的任何内容,你只需要做

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

希望这对你有用。

UpdateResultsLine方法中需要一个else语句。当需要Invoke时,您正在使用委托(调用)执行UpdateResultsLine方法,但随后您在不使用Invoke 的情况下再次调用

另外,为什么要使用BeginInvoke(异步)和Invoke(同步)?你确定没有同步问题吗?使用Invoke并添加else语句可以解决您的问题:

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