如何在富文本框中搜索字符串并突出显示所有找到的内容或突出显示每一行? [英] How do you search for a string in a rich text box and highlight all found or highlight each line?

查看:162
本文介绍了如何在富文本框中搜索字符串并突出显示所有找到的内容或突出显示每一行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了以下代码 http://www.dotnetcurry.com/showarticle.aspx ?ID = 146 并将其实现到我的应用程序中,但是它只能找到一次字符串,然后继续查找字符串的其他实例,就必须不断按下搜索按钮(100个匹配项有点乏味).

I found the following code http://www.dotnetcurry.com/showarticle.aspx?ID=146 and implemented it into my app, however it only finds the string once and to continue looking for other instances of the string you have to keep pressing the search button (bit tedious with 100's of matches).

我想查找搜索字符串的所有实例,如果可以的话,请高亮显示每一行,否则就不能像该代码那样突出显示字符串项,而是所有实例不只是一个.

I'd like to find all instances of the search string and if possible highlight each line, failing that highlight the string item like this code already does but all instances not just one.

在上面的链接上,页面上可能还有一个解决方案,但是它在VB中,我不知道如何转换为C#.

On the link above there is possibly a solution down further on the page but it's in VB which I don't know how to convert to C#.

private void btnListSearch_Click(object sender, EventArgs e)
    {
        int startindex = 0;
        if (txtSearch.Text.Length > 0)
            startindex = FindMyText(txtSearch.Text.Trim(), start, rtb.Text.Length);
        // If string was found in the RichTextBox, highlight it
        if (startindex >= 0)
        {
            // Set the highlight color as red
            rtb.SelectionColor = Color.Red;
            // Find the end index. End Index = number of characters in textbox
            int endindex = txtSearch.Text.Length;
            // Highlight the search string
            rtb.Focus();
            rtb.Select(startindex, endindex);
            // mark the start position after the position of 
            // last search string
            start = startindex + endindex;
        }
    }

    public int FindMyText(string txtToSearch, int searchStart, int searchEnd)
    {
        // Unselect the previously searched string
        if (searchStart > 0 && searchEnd > 0 && indexOfSearchText >= 0)
        {
            rtb.Undo();
        }
        // Set the return value to -1 by default.
        int retVal = -1;
        // A valid starting index should be specified.
        // if indexOfSearchText = -1, the end of search
        if (searchStart >= 0 && indexOfSearchText >=0)
        {
            // A valid ending index 
            if (searchEnd > searchStart || searchEnd == -1)
            {
                // Find the position of search string in RichTextBox
                indexOfSearchText = rtb.Find(txtToSearch, searchStart, searchEnd, RichTextBoxFinds.None);
                // Determine whether the text was found in richTextBox1.
                if (indexOfSearchText != -1)
                {
                    // Return the index to the specified search text.
                    retVal = indexOfSearchText;
                }
            }
        }
        return retVal;
    }

    private void txtSearch_TextChanged(object sender, EventArgs e)
    {
    // Reset the richtextbox when user changes the search string
        start = 0;
        indexOfSearchText = 0;
    }

我还尝试搜索列表框,但它只会在一行的开头而不是沿行查找字符串.

I also tried to search a listbox but it would only find strings at the start of a line not along the line.

string searchString = textBox2.Text;
        listBoxResults.SelectionMode = SelectionMode.MultiExtended;
        // Set our intial index variable to -1.
        int x = -1;
        // If the search string is empty exit.
        if (searchString.Length != 0)
        {
            // Loop through and find each item that matches the search string.
            do
            {
                // Retrieve the item based on the previous index found. Starts with -1 which searches start.
                x = listBoxResults.FindString(searchString, x);
                // If no item is found that matches exit.
                if (x != -1)
                {
                    // Since the FindString loops infinitely, determine if we found first item again and exit.
                    if (listBoxResults.SelectedIndices.Count > 0)
                    {
                        if (x == listBoxResults.SelectedIndices[0])
                            return;
                    }
                    // Select the item in the ListBox once it is found.
                    listBoxResults.SetSelected(x, true);
                }

            } while (x != -1);
        }

推荐答案

您的代码有一些问题.

Your code has a few problems.

  • 您每次单击按钮仅调用一次搜索和选择例程,因此每次只能找到一次.如果要突出显示所有出现的事件,则需要创建一个循环

  • You call the search and selection routines only once per button click, so only one occurrence can be found each time. If you want to highlight all occurrences you need to create a loop

您可以撤消FindMyText方法中的每个更改.这是没有意义的.您可能想之前清除所有选择,而不是在搜索过程中

You undo each change in the FindMyText method. That makes no sense. You may want to clear all selections before you search something new, but not while searching

在设置选择之前,先设置选择颜色.充其量也无济于事.

You set the selection color before setting the selection. This will do nothing, at best..

这里是一个将所有位置存储在列表中并支持两个按钮来在列表中前进和后退的版本.

Here is a version which stores all positions in a list and supports two buttons to go forward and backward through the list..:

List<int> found = null;

private void cb_findAll_Click(object sender, EventArgs e)
{
    int cursorPos = rtb.SelectionStart; 
    clearHighlights(rtb);
    found = FindAll(rtb, txtSearch.Text, 0);
    HighlightAll(rtb, Color.Red, found, txtSearch.Text.Length);
    rtb.Select(cursorPos, 0);   
}

private void cb_findNext_Click(object sender, EventArgs e)
{
    int pos = -1;
    for (int f = 0; f < found.Count; f++)
        if (found[f] > rtb.SelectionStart) { pos = found[f]; break; }
    if (pos >= 0) rtb.Select(pos, txtSearch.Text.Length);
    rtb.ScrollToCaret();
}

private void cb_findPrev_Click(object sender, EventArgs e)
{
    int pos = -1;
    for (int f = 0; f < found.Count; f++)
        if (found[f] >= rtb.SelectionStart) { if (f >= 1) pos = found[f - 1]; break; }
    if (pos >= 0) rtb.Select(pos, txtSearch.Text.Length);
    rtb.ScrollToCaret();
}

public List<int> FindAll(RichTextBox rtb, string txtToSearch, int searchStart)
{
    List<int> found = new List<int>();
    if (txtToSearch.Length <= 0) return found;

    int pos= rtb.Find( txtToSearch, searchStart, RichTextBoxFinds.None);
    while (pos >= 0)
    {
        found.Add(pos);
        pos = rtb.Find(txtToSearch, pos + txtToSearch.Length, RichTextBoxFinds.None);
    }
    return found;
}

public void HighlightAll(RichTextBox rtb, Color color, List<int> found, int length)
{
    foreach (int p in found)
    {
        rtb.Select(p, length);
        rtb.SelectionColor = color;
    }
}

void clearHighlights(RichTextBox rtb)
{
    int cursorPos = rtb.SelectionStart;    // store cursor
    rtb.Select(0, rtb.TextLength);         // select all
    rtb.SelectionColor = rtb.ForeColor;    // default text color
    rtb.Select(cursorPos, 0);              // reset cursor
}


private void txtSearch_TextChanged(object sender, EventArgs e)
{
    found = new List<int>();         // clear list
    clearHighlights(rtb);            // clear highlights
}
private void rtb_TextChanged(object sender, EventArgs e)
{
    found = new List<int>();
    clearHighlights(rtb);
}

请注意每段代码有多小!

Note how small each piece of code is!

这篇关于如何在富文本框中搜索字符串并突出显示所有找到的内容或突出显示每一行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆