如何在富文本框中搜索字符串并突出显示所有找到的或突出显示每一行?

时间:2014-10-23 14:27:33

标签: c# listbox richtextbox

我找到了以下代码http://www.dotnetcurry.com/showarticle.aspx?ID=146并将其实现到我的应用程序中,但它只找到一次字符串并继续查找字符串的其他实例,您必须按住搜索按钮(有点单调乏味100& #39;匹配)。

我想找到搜索字符串的所有实例,并且如果可能的话突出显示每一行,如果没有突出显示字符串项,就像这段代码已经完成但所有实例不仅仅是一行。

在上面的链接上,页面上可能还有一个解决方案,但它在VB中我不知道如何转换为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;
    }

我还试图搜索一个列表框,但它只会在不在该行的行的开头找到字符串。

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

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题。

  • 每按一次按钮,您只能调用一次搜索和选择例程,因此每次只能找到一次。如果要突出显示创建循环所需的所有实例

  • 您撤消FindMyText方法中的每项更改。这是没有意义的。您可能希望清除所有选择之前搜索新内容,但不能搜索

  • 在设置选择之前设置选择颜色。这最多只能做什么..

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

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

注意每段代码的小小!