我有两种方法可以在我的WPF应用中搜索文本文档。在第一次搜索中搜索单词时,它可以正常工作,但是当我向其添加单词时,它会崩溃并出现空异常。有人可以帮忙吗?
崩溃:
TextRange result = new TextRange(start, start.GetPositionAtOffset(searchText.Length));
堆栈跟踪:
{“值不能为空。\ r \ nParameter name:position2”}
示例:
如果文字说的话。
我搜索“if the”,然后我搜索“如果文字说”它会崩溃。
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;
}
答案 0 :(得分:1)
GetPositionAtOffset
如果找不到此位置,则返回null。见TextPointer.GetPositionAtOffset。在您的情况下,您会看到它,因为您进行搜索直到您没有到达搜索范围的末尾,但是例如,当您的搜索范围包含100个符号并且您的搜索文本在索引91处到达指针后有10个符号时 - 您将使用偏移量10调用GetPositionAtOffset
- 这将是101符号,在这种情况下为null
。 您可以在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
循环,只需添加此特殊检查。
看起来你正在搜索,所以只想给你两个建议:
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。