2013-10-18 76 views
3

我有兩種方法在我的WPF應用程序中搜索文本文檔。當在第一次搜索中搜索一個單詞時,它可以正常工作,但是當我向它添加一個單詞時,它會崩潰併產生一個空異常。有人可以幫忙嗎?通過文本窗口搜索應用程序崩潰

崩潰上:

TextRange result = new TextRange(start, start.GetPositionAtOffset(searchText.Length)); 

堆棧跟蹤:

{ 「值不能爲空\ r \ n參數名:位置2」}

實施例:

如果文字說明了這一點。

而我搜索「if the」,然後我搜索「if the text said」it crash。

 private void btnSearch_Click(object sender, RoutedEventArgs e) 
     { 
      string searchText = searchBox.Text.Trim(); 
      searchText = searchText.ToLower(); 

      if (String.IsNullOrWhiteSpace(searchText)) 
      { 
       MessageBox.Show("Please enter a search term!"); 
       searchBox.Clear(); 
       searchBox.Focus(); 
       newSearch = true; 
       return; 
      } 

      if (!String.IsNullOrEmpty(lastSearch)) 
       { 
       if (lastSearch != searchText) 
        newSearch = true; 
      } 

      TextRange searchRange; 

      RichTextBox _body = ((DockPanel)((TabItem)tabControl.Items[tabControl.SelectedIndex]).Content).Children[1] as RichTextBox; 
      _body.Focus(); 

      if (newSearch) 
      { 
       searchRange = new TextRange(_body.Document.ContentStart, _body.Document.ContentEnd); 
       lastSearch = searchText; 
       TextPointer position2 = _body.Document.ContentEnd; 
      } 

      else 
      { 
       backupSearchRange = new TextRange(_body.CaretPosition.GetLineStartPosition(1) == null ? 
        _body.CaretPosition.GetLineStartPosition(0) : _body.CaretPosition.GetLineStartPosition(1), _body.Document.ContentEnd); 



       TextPointer position1 = _body.Selection.Start.GetPositionAtOffset(1); 
       TextPointer position2 = _body.Document.ContentEnd; 

       searchRange = new TextRange(position1, position2); 
      } 

      TextRange foundRange = newSearchFunction(searchRange, searchText); 

      if (foundRange == null) 
      { 
       if (newSearch) 
       { 
        MessageBox.Show("\'" + searchBox.Text.Trim() + "\' not found!"); 
        newSearch = true; 
        lastOffset = -1; 
       } 

       else 
       { 
        MessageBox.Show("No more results!"); 
        newSearch = true; 
        lastOffset = -1; 
       } 
      } 

      else 
      { 
       _body.Selection.Select(foundRange.Start, foundRange.End); 
       _body.SelectionBrush = selectionHighlighter; 
       newSearch = false; 
      } 
     }  

 private TextRange newSearchFunction(TextRange searchRange, string searchText) 
     { 
      int offset = searchRange.Text.ToLower().IndexOf(searchText); 
       offset = searchRange.Text.ToLower().IndexOf(searchText); 

      if (offset < 0) 
       return null; 

      if (lastOffset == offset) 
      { 
       //searchRange = backupSearchRange; 

       offset = searchRange.Text.ToLower().IndexOf(searchText); 

       if (offset < 0) 
        return null; 

       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.ToLower() == searchText) 
        { 
         lastOffset = offset; 
         return result; 
        } 
       } 

      } 

      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.ToLower() == searchText) 
       { 
        lastOffset = offset; 
        return result; 
       } 
      } 

      return null; 
     } 
+1

顯然'start.GetPositionAtOffset(searchText.Length)'返回null。另外,GetPositionAtOffset以符號而不是字符工作,這可能會讓你感覺不舒服。 –

+0

我編輯了你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 –

回答

1
  1. 方法GetPositionAtOffset可以返回null,如果它不能找到這個位置。見TextPointer.GetPositionAtOffset。在你的情況下,你會看到它,因爲你搜索了,直到你沒有達到你的搜索範圍的末尾,但是當你的搜索範圍包含100個符號,而你的搜索文本在索引91到達指針後有10個符號 - 您將撥打GetPositionAtOffset,並且偏移量爲10 - 這將是101符號,在這種情況下會給您null
  2. 你可以在你的for循環簡單的檢查,是這樣的:

    for (
        TextPointer start = searchRange.Start.GetPositionAtOffset(offset); 
        start != searchRange.End; 
        start = start.GetPositionAtOffset(1)) 
    { 
        var end = start.GetPositionAtOffset(searchText.Length); 
        if (end == null) 
        { 
         break; 
        } 
    
        TextRange result = new TextRange(start, end); 
    
        if (result.Text.ToLower() == searchText) 
        { 
         lastOffset = offset; 
         return result; 
        } 
    } 
    

    你有一個更類似於for循環,只是把它添加這個特殊檢查過。

  3. 看起來你正在做的搜索,所以只是想給你兩個建議:

    • 使用string.Compare方法,而不是ToLower。見String.Compare Method (String, String, Boolean, CultureInfo)。你的情況應該是string.Compare(text1, text2, ignoreCase: true, culture: CultureInfo.CurrentCulture)。在這種情況下您的應用程序將支持所有語言。
    • 如果您確實想使用ToLower並以這種方式進行搜索 - 請考慮將其更改爲ToUpper,因爲某些語言在執行ToLower時可能會非常棘手。檢查這篇文章What's Wrong With Turkey?。當您在土耳其語語言環境中執行ToLower(I)時,您將獲得dotless i,這與i不同。維基百科關於:Dotted and dotless I
相關問題