C# 通过文本窗口应用程序崩溃进行搜索

C# 通过文本窗口应用程序崩溃进行搜索,c#,wpf,c#-4.0,C#,Wpf,C# 4.0,我有两种方法可以在我的WPF应用程序中搜索文本文档。当在第一次搜索中搜索一个单词时,它工作正常,但当我向其中添加一个单词时,它将崩溃并出现一个空异常。有人能帮忙吗 发生在: TextRange result = new TextRange(start, start.GetPositionAtOffset(searchText.Length)); 堆栈跟踪: {“值不能为空。\r\n参数名称:position2”} 例如: 如果文本中说了这一点 我搜索“如果”,然后搜索“如果文本说”它会崩溃

我有两种方法可以在我的WPF应用程序中搜索文本文档。当在第一次搜索中搜索一个单词时,它工作正常,但当我向其中添加一个单词时,它将崩溃并出现一个空异常。有人能帮忙吗

发生在:

TextRange result = new TextRange(start, start.GetPositionAtOffset(searchText.Length));
堆栈跟踪:

{“值不能为空。\r\n参数名称:position2”}

例如:

如果文本中说了这一点

我搜索“如果”,然后搜索“如果文本说”它会崩溃

        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);
如果(偏移量<0)
返回null;
如果(lastOffset==偏移量)
{
//搜索范围=备份搜索范围;
offset=searchRange.Text.ToLower().IndexOf(searchText);
如果(偏移量<0)
返回null;
对于(TextPointer start=searchRange.start.GetPositionAtOffset(偏移量);start!=searchRange.End;start=start.GetPositionAtOffset(1))
{
TextRange结果=新的TextRange(start,start.GetPositionAtOffset(searchText.Length));
if(result.Text.ToLower()==searchText)
{
lastOffset=偏移量;
返回结果;
}
}
}
对于(TextPointer start=searchRange.start.GetPositionAtOffset(偏移量);start!=searchRange.End;start=start.GetPositionAtOffset(1))
{
TextRange结果=新的TextRange(start,start.GetPositionAtOffset(searchText.Length));
if(result.Text.ToLower()==searchText)
{
lastOffset=偏移量;
返回结果;
}
}
返回null;
}
  • 方法
    getPositionOffset
    如果找不到此位置,则可以返回null。看见在你的例子中,你看到它是因为你一直在搜索,直到你没有到达你的搜索范围的尽头,但是在例如你的搜索范围包含100个符号,并且你的搜索文本在你到达索引91的指针后有10个符号的情况下,你将调用偏移量为10的
    GetPositionAtOffset
    ,这将是101个符号,在这种情况下,它将为您提供
    null
  • 您可以对
    循环执行简单的检查,例如:

    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。将
      方法改为
      ToLower
      。看见在您的情况下,它应该是
      string.Compare(text1,text2,ignoreCase:true,culture:CultureInfo.CurrentCulture)
      。在这种情况下,您的应用程序将支持所有语言 <>如果你真的想使用<代码> ToLower < /代码>并以这种方式进行搜索-考虑把它改为<代码> ToupPu/Cuth>,因为当你做ToLower时,有些语言可能会很棘手。检查这篇文章。当你在土耳其语言环境下使用
      ToLower(I)
      时,你会得到
      dotless I
      ,这与
      I
      不同。维基百科关于:

  • 显然
    start.GetPositionAtOffset(searchText.Length)
    返回null。此外,GetPositionAtOffset在符号中而不是在字符中工作,这可能会让您大吃一惊。我已经编辑了您的标题。请参阅“”,其中的共识是“不,他们不应该”。
    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;
        }
    }