2015-07-20 108 views
3

我找到了下一個和上一個函數並對其進行了編輯,以便當用戶在文本框中選擇文本並單擊查找下一個或查找上一個按鈕時,查找功能將從其索引開始選定的字符並遍歷每個搜索結果(最初該功能不在那裏)。要獲得所選文本的起始索引我創建了一個功能:在TextSelectionChanged上保留單詞索引

private int GetIntialCharPos(string Text) 
{ 
    int row = Variables._TextBox.GetLineIndexFromCharacterIndex(Variables._TextBox.CaretIndex); 
    int col = Variables._TextBox.CaretIndex - Variables._TextBox.GetCharacterIndexFromLineIndex(row); 
    return col; 
} 

這確實查找下一個和以前去如下功能:

private List<int> _matches; 
    private string _textToFind; 
    private bool _matchCase; 
    private int _matchIndex; 

    private void MoveToNextMatch(string textToFind, bool matchCase, bool forward) 
    { 
     if (_matches == null || _textToFind != textToFind || _matchCase != matchCase) 
     { 
      int startIndex = 0, matchIndex; 
      StringComparison mode = matchCase ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase; 

      _matches = new List<int>(); 
      while (startIndex < Variables._TextBox.Text.Length && (matchIndex = Variables._TextBox.Text.IndexOf(textToFind, startIndex, mode)) >= 0) 
      { 
       _matches.Add(matchIndex); 
       startIndex = matchIndex + textToFind.Length; 
      } 

      _textToFind = textToFind; 
      _matchCase = matchCase; 
      _matchIndex = forward ? _matches.IndexOf(GetIntialCharPos(textToFind)) : _matches.IndexOf(GetIntialCharPos(textToFind)) - 1; 
     } 
     else 
     { 
      _matchIndex += forward ? 1 : -1; 
      if (_matchIndex < 0) 
      { 
       _matchIndex = _matches.Count - 1; 
      } 
      else if (_matchIndex >= _matches.Count) 
      { 
       _matchIndex = 0; 
      } 
     } 

     if (_matches.Count > 0) 
     { 
      Variables._TextBox.SelectionStart = _matches[_matchIndex]; 
      Variables._TextBox.SelectionLength = textToFind.Length; 
      Variables._TextBox.Focus(); 
     } 
    } 

我的問題是,一旦用戶選擇他需要搜索的文本,並通過查找下一個和上一個按鈕,然後他決定從不同的索引中選擇文本,而不是繼續從所選索引搜索,它將保持默認的初始順序而不是從選定的索引開始,並從中得出每個結果。我創建了一個小gif video here,以便您可以更好地瞭解這個問題。

如何保留選定的單詞索引,以便每次用戶從不同的索引中選擇時,都可以從用戶選擇的索引開始搜索,而不是始終從頭開始搜索。

回答

3
private int _matchIndex; 

這就是你的問題變量。它保留最後的匹配索引,但不知道用戶何時自己更改它。 TextBox類沒有SelectionChanged事件來告訴你它,所以沒有簡單的方法來重置變量。

只需使用RichTextBox代替,它的確有that event

但是這很容易發生,因爲您通過將搜索操作拆分爲單獨的類而不必要地添加了狀態。狀態通常是一件壞事,它是一個錯誤發生器。你可以平凡使整個操作無國籍直接使用文本框對象:

private static void MoveToNextMatch(TextBoxBase box, bool forward) { 
     var needle = box.SelectedText; 
     var haystack = box.Text; 
     int index = box.SelectionStart; 
     if (forward) { 
      index = haystack.IndexOf(needle, index + 1); 
      if (index < 0) index = haystack.IndexOf(needle, 0); 
     } 
     else { 
      if (index == 0) index = -1; 
      else index = haystack.LastIndexOf(needle, index - 1); 
      if (index < 0) index = haystack.LastIndexOf(needle, haystack.Length - 1); 
     } 
     if (index >= 0) { 
      box.SelectionStart = index; 
      box.SelectionLength = needle.Length; 
     } 
     box.Focus(); 
    } 

使用最後/的IndexOf()方法,它接受StringComparison實施matchCase說法。

+0

我正在使用wpf文本框,並且有一個選擇已更改的事件可用。但我想這個代碼會工作,因爲我認爲你編寫的代碼不需要使用選擇更改的事件。我出來了,我會測試它,並讓你知道 –

+0

我將如何循環調查結果,即當我到達特定突出顯示文本的末尾時,單擊Next或Previous,我如何開始再次搜索?此刻如果我繼續點擊下一步,它將在最後一期結束,如果我點擊之前它會引發索引超出範圍錯誤。 –

+0

這確實是一個錯誤,修復並做了換行。 –