如何查找下一个和上一个搜索字符串?

时间:2016-11-25 23:16:37

标签: c# string

所以我试图创建一个GUI,用于在richtextbox中查找用户搜索到的单词。我有两个按钮,一个用于查找字符串的下一个位置并突出显示,另一个按钮用于查找搜索到的字符串的先前位置。我的“下一步”按钮工作正常,每次单击时突出显示文本中的下一个字符串位置。但我以前的按钮似乎不起作用。我做错了什么?

int index = 0;

       //NEXT BUTTON
private void button2_Click(object sender, EventArgs e)
    {
        richTextBox1.SelectionBackColor = Color.White;
        richTextBox1.Find(textBox2.Text, index, richTextBox1.TextLength, RichTextBoxFinds.None);
        richTextBox1.SelectionBackColor = Color.Yellow;
        index = richTextBox1.Text.IndexOf(textBox2.Text, index) + 1;
    }

           // PREVIOUS BUTTON
private void button1_Click(object sender, EventArgs e) 
    {
        richTextBox1.Find(textBox2.Text, index -1, richTextBox1.TextLength, RichTextBoxFinds.None);
        richTextBox1.SelectionBackColor = Color.White;
        index = richTextBox1.Text.IndexOf(textBox2.Text, index) - 1;
    }

2 个答案:

答案 0 :(得分:2)

您不需要自己计算新索引。使用Find方法的结果,它为您提供正确的索引。如果要向后搜索,请使用RichTextBoxFinds.Reverse。在上一次按钮中,您也没有将颜色设置为黄色。

已编辑的代码。它现在可以正常工作。

num1    num2    i       output
0       0       0       0
1       1       1       1
4       5       2       4
9       14      3       9
16      30      4       16
                5       30

答案 1 :(得分:0)

我知道这是一个较晚的答案,但是我终于找到了解决该问题的方法。希望可以帮助别人。这将根据RichTextBox中当前插入符号的位置查找并选择要搜索的下一个/上一个单词。它不区分大小写,并且会忽略隐藏的XAML字符,即,如果您搜索格式化的文本,它将实际上找到它。

使用下面的SelectWord()方法从搜索框中传递文本。将此方法绑定到您的下一个/上一个按钮,如下所示。我在开发此代码时学到的一个有用技巧是使用TextRange在2个文本指针之间显示文本 例如字符串debugText = new TextRange(texpointer1,textpointer2).Text;

    private void PreviousButton_Click(object sender, RoutedEventArgs e)
    {
        SelectWord(SearchTextbox.Text, LogicalDirection.Backward);
    }

    private void NextButton_Click(object sender, RoutedEventArgs e)
    {
        SelectWord(SearchTextbox.Text, LogicalDirection.Forward);
    }

    /// <summary>
    /// Takes a string input and searches richtextbox in the direction specified.  
    /// </summary>
    private void SelectWord(string input, LogicalDirection direction)
    {
        RichTextBox rtb = ClRichTextBox; //the name of your richtextbox control

        TextPointer currentStartposition = rtb.Selection.Start;
        TextPointer currentEndposition = rtb.Selection.End;
        TextPointer position;
        TextPointer previousPosition;
        string textLine = null;
        if (direction == LogicalDirection.Forward)
        {
            position = currentStartposition.GetLineStartPosition(1);
            previousPosition = currentEndposition;
            if (position != null)
                textLine = new TextRange(previousPosition, position).Text;
        }
        else
        {
            position = currentStartposition.GetLineStartPosition(0);
            previousPosition = currentStartposition;
            if (position != null)
                textLine = new TextRange(position, previousPosition).Text;
        }

        while (position != null)
        {
            int indexInRun;
            if (direction == LogicalDirection.Forward)
                indexInRun = textLine.IndexOf(input, StringComparison.CurrentCultureIgnoreCase);
            else
                indexInRun = textLine.LastIndexOf(input, StringComparison.CurrentCultureIgnoreCase);

            if (indexInRun >= 0)
            {
                TextPointer nextPointer = null;
                if (direction == LogicalDirection.Forward)
                    position = previousPosition;

                int inputLength = input.Length;
                while (nextPointer == null)
                {
                    if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text && nextPointer == null) //checks to see if textpointer is actually text
                    {
                        string textRun = position.GetTextInRun(LogicalDirection.Forward);
                        if (textRun.Length - 1 < indexInRun)
                            indexInRun -= textRun.Length;
                        else //found the start position of text pointer
                        {
                            position = position.GetPositionAtOffset(indexInRun);
                            nextPointer = position;
                            while (inputLength > 0)
                            {
                                textRun = nextPointer.GetTextInRun(LogicalDirection.Forward);
                                if (textRun.Length - indexInRun < inputLength)
                                {
                                    inputLength -= textRun.Length;
                                    indexInRun = 0; //after the first pass, index in run is no longer relevant
                                }
                                else
                                {
                                    nextPointer = nextPointer.GetPositionAtOffset(inputLength);
                                    rtb.Selection.Select(position, nextPointer);
                                    rtb.Focus();

                                    //moves the scrollbar to the selected text
                                    Rect r = position.GetCharacterRect(LogicalDirection.Forward);
                                    double totaloffset = r.Top + rtb.VerticalOffset;
                                    rtb.ScrollToVerticalOffset(totaloffset - rtb.ActualHeight / 2);
                                    return; //word is selected and scrolled to. Exit method
                                }
                                nextPointer = nextPointer.GetNextContextPosition(LogicalDirection.Forward);
                            }


                        }
                    }
                    position = position.GetNextContextPosition(LogicalDirection.Forward);
                }
            }

            previousPosition = position;
            if (direction == LogicalDirection.Forward)
            {
                position = position.GetLineStartPosition(1);
                if (position != null)
                    textLine = new TextRange(previousPosition, position).Text;
            }
            else
            {
                position = position.GetLineStartPosition(-1);
                if (position != null)
                    textLine = new TextRange(position, previousPosition).Text;
            }

        }

        //if next/previous word is not found, leave the current selected word selected
        rtb.Selection.Select(currentStartposition, currentEndposition);
        rtb.Focus();
    }