从另一个线程获取 richtextbox.text



我不敢相信以前没有问过这个问题,但我在这里找不到参考资料。对不起,如果我错过了!!有很多关于更新 rtb 的内容。来自线程的文本,但在获取 rtb 时很少或没有。发短信。

我需要从另一个线程的 UI 线程上的富文本框中获取文本值,然后能够遍历同一富文本框的每一行。

我想调用和委托是必需的,但如何制作它们?

例如,如果代码位于同一线程中,则如下所示:

private void checkRtbEntries()
{
    if (rtb.Text != "")
    {
        foreach (string textLine in rtb.Lines)
        {
            // do some things in the background thread 
            // based on the rtb line content...
        }
    }
}

但是,checkRtbEntries() 是从 Backgroundworker 线程中调用的,而 rtb 在 UI 线程中,因此抛出无效的跨线程操作。

运行 BackgroundWorker 线程时,可以选择向其传递参数,其他线程可以引用和使用参数:

myWorker.RunWorkerAsync(rtb.Text);

DoWork 事件中,将参数强制转换为字符串并对其执行操作。

var myRtbText = e.Argument.ToString();

这样,您的后台线程实际上永远不会接触 UI 线程。

如果需要在后台工作线程运行时对主线程上的元素进行更改,则需要使用 ProgressChanged 事件。

由于在 DoWork 事件中没有对RichTextBox的引用(只有其 Text 属性的内容),因此实际上无法在原始文本框上调用 Lines 属性。

不过,您应该能够非常轻松地模拟它("\r"、"\r"和""的实际Lines属性测试,但Environment.NewLine应该为您解决这个问题):

var allLines
    = myRtbText.Split(new[] {Environment.NewLine}, StringSplitOptions.None);

(如果要忽略空行,请使用 StringSplitOptions.RemoveEmptyItems。

这是从后台跳转到 UI 线程的常用方法(对于每个控件)

 private delegate void checkRichTextBoxDelegate(); 
 private void checkRtbEntries() 
 { 
     if (this.rtb.InvokeRequired) 
     { 
         checkRichTextBoxDelegate checkEntries = new checkRichTextBoxDelegate(checkRtbEntries); 
         this.Invoke(checkRtbEntries); 
     } 
     else 
     { 
         .... do your work on the RichTextBox, you are on the UI thread
     } 
 } 

最新更新