【问题标题】:How do you search for a string in a rich text box and highlight all found or highlight each line?如何在富文本框中搜索字符串并突出显示所有找到的内容或突出显示每一行?
【发布时间】:2014-10-23 14:27:33
【问题描述】:

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

我想找到搜索字符串的所有实例,如果可能的话,突出显示每一行,如果没有像这段代码那样突出显示字符串项,但所有实例不只是一个。

在上面的链接中,页面下方可能有一个解决方案,但它是在 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);
        }

【问题讨论】:

  • 请正确缩进代码以获得更好的可读性。

标签: c# listbox richtextbox


【解决方案1】:

您的代码存在一些问题。

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

  • 您可以撤消 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);
}

注意每段代码有多小!

【讨论】:

  • 嗨 TaW 我在这个位 rtb.Select(startindex, 0); InvalidArgument='-1' 的值对'start' 无效。参数名称:开始
  • 哎呀,一个错字.. 看我更正的答案!我现在将光标重置为存储的值..
  • 现在关闭,如果我搜索某些内容然后更改搜索条件不会再次搜索,直到我清除文本框单击搜索然后输入要搜索的字符串并再次单击按钮。也许它需要这个回来? // 当用户更改搜索字符串时重置富文本框 start = 0; indexOfSearchText = 0;
  • 没有。它需要在点击中重置开始变量 - 请参阅更正的答案!不过,我正在睡觉。我会在早上清理整个代码..
  • 谢谢 TaW,我想知道是否只有一个搜索字符串的结果应该在该字符串处停止并突出显示,此时它滚动到富文本框的末尾您必须向上滚动才能找到突出显示的文本,让我知道您对最佳选项的看法。下一步和后退按钮怎么样,在此之后我可能需要向您发送一些 $$ :-)
猜你喜欢
  • 1970-01-01
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
  • 2012-06-26
  • 1970-01-01
  • 2013-08-07
相关资源
最近更新 更多