문제

나는 지금 너무 오랫동안 사용하여 문제를 알아 내려고 노력했습니다.

거래는 다음과 같습니다.

C# 및 WPF를 사용하여 작은 응용 프로그램을 작성하고 있습니다.

FlowDocument가 포함 된 RichTextBox가 있습니다.

리치 텍스트 박스 아래에 작은 텍스트 상자와 버튼을 추가했습니다.

그런 다음 사용자는 검색하고자하는 단어를 입력하고 버튼을 누릅니다.

그런 다음 RichTextBox는 그 단어의 첫 번째 발생으로 이동합니다.

RichTextBox가 단어로 스크롤되는 한, 단어로 커서를 선택, 강조 또는 강조 표시하거나 배치 할 수도 있습니다.

버튼을 계속 누르면 문서의 끝이 끝날 때까지 다음으로 단어의 다음과 같은 상황으로 이동합니다.

내가 말했듯이 - 나는 그것이 간단한 일이라고 생각했지만 이것을 알아내는 데 심각한 문제가 있습니다.

도움이 되었습니까?

해결책

이것은 작업을 수행해야합니다.

public bool DoSearch(RichTextBox richTextBox, string searchText, bool searchNext)
{
  TextRange searchRange;

  // Get the range to search
  if(searchNext)
    searchRange = new TextRange(
        richTextBox.Selection.Start.GetPositionAtOffset(1),
        richTextBox.Document.ContentEnd);
  else
    searchRange = new TextRange(
        richTextBox.Document.ContentStart,
        richTextBox.Document.ContentEnd);

  // Do the search
  TextRange foundRange = FindTextInRange(searchRange, searchText);
  if(foundRange==null)
    return false;

  // Select the found range
  richTextBox.Selection.Select(foundRange.Start, foundRange.End);
  return true; 
}

public TextRange FindTextInRange(TextRange searchRange, string searchText)
{
  // Search the text with IndexOf
  int offset = searchRange.Text.IndexOf(searchText);
  if(offset<0)
    return null;  // Not found

  // Try to select the text as a contiguous range
  for(TextPointer start = searchRange.Start.GetPositionAtOffset(offset); start != searchRange.End; start = start.GetPositionAtOffset(1))
  {
    TextRange result = new TextRange(start, start.GetPositionAtOffset(searchText.Length);
    if(result.Text == searchText)
      return result;
  }
  return null;
}

FindTextInRange의 for () 루프의 이유 불행히도 범위는 텍스트가 아닌 문자를 제거하므로 경우에 따라 indexof에 의해 계산 된 오프셋이 약간 낮습니다.

다른 팁

나는 다른 접근법을 사용했습니다. 텍스트 상자를 사용하여 키워드를 설정합니다. 버튼 클릭의 키워드를 검색합니다. 키워드를 찾습니다. Highlighs를하고 그 키워드에 중점을 둡니다.

    // Index of Current Result Found (Counts Characters not Lines or Results)
    private int IndexOfSearchResultFound;
    // Start Position Index of RichTextBox (Initiated as 0 : Beggining of Text / 1st Char)
    private int StartOfSelectedKeyword;
    private int EndOfSelectedKeyword;

    private void btnSearch_Click(object sender, EventArgs e)
    {
        // Reset Keyword Selection Index. (0 is the Staring Point of the Keyword Selection)
        IndexOfSearchResultFound = 0;

        // Specify the End of the Selected Keyword; using txt_Search.Text.Lenght (Char Ammount).
        EndOfSelectedKeyword = txt_Search.Text.Length;

        // If txt_Search.Text is not Empty
        if (txt_Search.Text.Length > 0)
        {
            // Find Keyword in RichTextBox.Text
            IndexOfSearchResultFound = FindKeyword(txt_Search.Text.Trim(), StartOfSelectedKeyword, rtb_Hosts.Text.Length);

            // If string was found in RichTextBox; Highlight it and Focus on Keyword Found Location
            if (IndexOfSearchResultFound >= 0)
            {
                // Focus on Currently Found Result
                rtb_Hosts.Focus();

                // Highlight the search string
                rtb_Hosts.Select(IndexOfSearchResultFound, EndOfSelectedKeyword);

                // Sets a new Starting Position (after the Position of the Last Result Found)
                // To be Ready to Focus on the Next Result
                StartOfSelectedKeyword = IndexOfSearchResultFound + EndOfSelectedKeyword;
            }
        }
    }


    private int FindKeyword(string _SearchKeyword, int _KeywordSelectionStart, int _KeywordSelectionEnd)
    {
        // De-Select Previous Searched String (Keyword)
        if (_KeywordSelectionStart > 0 && _KeywordSelectionEnd > 0 && IndexOfSearchResultFound >= 0)
        { rtb_Hosts.Undo(); }

        // Set the return value to -1 by default.
        int retVal = -1;

        // A valid Starting index should be specified.
        // if indexOfSearchText = -1, Means that Search has reached the end of Document
        if (_KeywordSelectionStart >= 0 && IndexOfSearchResultFound >= 0)
        {
            // Find Keyword
            IndexOfSearchResultFound = rtb_Hosts.Find(_SearchKeyword, _KeywordSelectionStart, _KeywordSelectionEnd, RichTextBoxFinds.None);

            // Determine whether the text was found in richTextBox
            retVal = IndexOfSearchResultFound;
        }
        // Return the index to the specified Keyword text.
        return retVal;
    }

아직 달성 할 수 없었던 유일한 것은 첫 번째 검색 결과로 돌아가는 것입니다.

이것은 일치를 찾을 수있는 변형입니다 캐럿 위치에 가장 가깝습니다.

  private TextRange FindText(string findText)
    {
      var fullText = DoGetAllText();
      if (string.IsNullOrEmpty(findText) || string.IsNullOrEmpty(fullText) || findText.Length > fullText.Length)
        return null;

      var textbox = GetTextbox();
      var leftPos = textbox.CaretPosition;
      var rightPos = textbox.CaretPosition;

      while (true)
      {
        var previous = leftPos.GetNextInsertionPosition(LogicalDirection.Backward);
        var next = rightPos.GetNextInsertionPosition(LogicalDirection.Forward);
        if (previous == null && next == null)
          return null; //can no longer move outward in either direction and text wasn't found

        if (previous != null)
          leftPos = previous;
        if (next != null)
          rightPos = next;

        var range = new TextRange(leftPos, rightPos);
        var offset = range.Text.IndexOf(findText, StringComparison.InvariantCultureIgnoreCase);
        if (offset < 0)
          continue; //text not found, continue to move outward

        //rtf has broken text indexes that often come up too low due to not considering hidden chars.  Increment up until we find the real position
        var findTextLower = findText.ToLower();
        var endOfDoc = textbox.Document.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
        for (var start = range.Start.GetPositionAtOffset(offset); start != endOfDoc; start = start.GetPositionAtOffset(1))
        {
          var result = new TextRange(start, start.GetPositionAtOffset(findText.Length));
          if (result.Text?.ToLower() == findTextLower)
          {
            return result;
          }
        }
      }
    }

경기를 강조하려면 경기를 찾을 때이 방법을 무효화하고이 작업을 수행하는 것만 큼 간단합니다.

textbox.Selection.Select(result.Start, result.End);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top