2009-11-18 3 views
5

지금은 길을 너무 오래 사용하여 문제를 파악하려고 노력했습니다. .간단한 검색 기능을 사용하여 검색 할 단어로 커서를 이동 (또는 강조 표시)

나는 C# 및 WPF를 사용하여 작은 응용 프로그램을 쓰고 있어요 : 여기

는 거래이다.

나는 RichDextBox에 FlowDocument가 있습니다.

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

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

그러면 richtextbox는 해당 단어의 첫 번째 발생으로 점프합니다.

그냥 올바른 줄로 점프하는 것만으로 충분합니다. richTextBox가 단어로 스크롤되는 한 아무 것도 할 단어로 커서를 선택, 강조 표시 또는 배치 할 수 있습니다.

버튼을 계속 누르면 문서의 끝까지 단어의 다음 번으로 이동합니다.

내가 말했듯이 - 나는 단순한 작업이라고 생각했지만 - 심각한 문제가 발생했다.

답변

13

이 작업을 수행해야합니다

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

경우에 따라서는 약간 것 같이 IndexOf에 의해 계산 된 오프셋 있도록 range.Text이 아닌 텍스트 문자를 제거합니다 FindTextInRangeUnfortunately에 대한() 루프 이유 너무 낮은.

+0

그것은 마법처럼 일했다 :

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

당신이 경기를 발견했을 때 다음이 무효화하기 위해이 방법을 변경하고이 일을 같이 간단 할 거라고 경기를 강조하려면

. 답장을 보내 주셔서 감사합니다. 너 내가 너를 얼마나 도왔는지 모르 잖아. 좋은 하루 되세요! – Sagi1981

+0

그러나 FindTextInRange의 첫 번째 반환은 false 대신 null로 변경되어야합니다. – Sagi1981

+2

Thanks. 그것은 아이디어를 입력하고 그것을 시도하는 것을 성가 시게하지 않을 때 일어납니다. 나는 그 대답을 거짓으로 편집했다. –

1

다른 접근 방식을 사용했습니다. TextBox를 사용하여 키워드 설정; 버튼 클릭시 KeyWord를 검색합니다. 키워드를 찾습니다. 그것을 강조하고 그 KeyWord에 중점을 둡니다. 나는 아직 달성 할 수

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

있는 유일한 방법은 1 차 검색 결과

0

이것은 캐럿 위치에 경기에 가장 가까운 를 찾을 변종이다에 반환하는 것입니다.

textbox.Selection.Select(result.Start, result.End);