搜索和突出显示功能的背景工作者

时间:2015-02-09 15:09:52

标签: c# winforms visual-studio

我有一个简单的while循环,允许我在文本框中查找文本,但是当我在文本框中搜索多次出现的单词时,它会锁定界面一段时间。我想把它移到后台工作者,但我不认为这可以做,因为接口元素(即textbox3.text)在主线程上。当涉及主界面元素时,如何创建后台工作者?

我在网上找到了不错的信息,但是我在实施其他解决方案时遇到了麻烦。

    public void button2_Click(object sender, EventArgs e)
    {
        //Highlight text when search button is clicked
        int index = 0;
        while (index < dragDropRichTextBox1.Text.LastIndexOf(textBox3.Text))
        {
            dragDropRichTextBox1.Find(textBox3.Text, index, dragDropRichTextBox1.TextLength, RichTextBoxFinds.None);
            dragDropRichTextBox1.SelectionBackColor = Color.Orange;
            index = dragDropRichTextBox1.Text.IndexOf(textBox3.Text, index) + 1;
        }
    }

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

我想你要做的是创建子线程来完成工作而不是阻止UI线程(伪代码,又名未测试):

public void button2_Click(object sender, EventArgs e)
{
    // Copy text in a non-thread protected string, to be used within the thread sub-routine.
    string searchText = textBox3.Text;
    string contentText = dragDropRichTextBox1.Text;

    // Create thread routine
    ThreadPool.QueueUserWorkItem(o => {

        // Iterate through all instances of the string.
        int index = 0;
        while (index < contentText.LastIndexOf(searchText))
        {
            dragDropRichTextBox1.Invoke((MethodInvoker) delegate {

                // Update control within UI thread
                //Highlight text when search button is clicked
                dragDropRichTextBox1.Find(searchText, index, contentText.Length, RichTextBoxFinds.None);
                dragDropRichTextBox1.SelectionBackColor = Color.Orange;
            }

            // Go to next instance
            index = contentText.IndexOf(searchText, index) + 1;
        }            
    });
}

同样,这是未经测试的,但这会给你一个想法。

- 编辑 -

您根本不需要线程,在dragDropRichTextBox1.SuspendLayout()dragDropRichTextBox1.ResumeLayout()之间完成所有工作就足够了。

    private void button1_Click(object sender, EventArgs e)
    {
        // Copy text in a non-thread protected string, to be used within the thread sub-routine.
        string searchText = textBox1.Text;
        string contentText = richTextBox1.Text;

        // Suspend all UI refresh, so time won't be lost after each Find
        richTextBox1.SuspendLayout();

        // Iterate through all instances of the string.
        int index = 0;
        while (index < contentText.LastIndexOf(searchText))
        {
            //Highlight text when search button is clicked
            richTextBox1.Find(searchText, index, contentText.Length, RichTextBoxFinds.None);
            richTextBox1.SelectionBackColor = Color.Orange;

            // Go to next instance
            index = contentText.IndexOf(searchText, index) + 1;
        }

        // Finally, resume UI layout and at once get all selections.
        richTextBox1.ResumeLayout();
    }

答案 1 :(得分:-1)

当你在后台线程中操作UI元素时,你只需要使用invoke

https://msdn.microsoft.com/en-us/library/vstudio/ms171728(v=vs.100).aspx

答案 2 :(得分:-1)

您可以在控件上调用Invoke方法。

dragDropRichTextBox1.Invoke((MethodInvoker) delegate {
  //Your code goes here for whatever you want to do. 
}

);

这应该可以解决您的问题。