C# 在RichTextBox\u TextChanged事件中使用TextPointer.GetLineStartPosition时出现StackOverflowException

C# 在RichTextBox\u TextChanged事件中使用TextPointer.GetLineStartPosition时出现StackOverflowException,c#,wpf,C#,Wpf,我有一个RichTextBox(RTB),旁边是一个DataGrid(DG)。用户可以将ID列表粘贴到RTB中,以便对其执行一些批量操作。为了让用户知道他们传入RTB的ID是否不在DG中,我想更改文本的颜色 这就是我目前的情况: private void RichTextBox\u TextChanged(对象发送者,textchangedventargs e) { //TODO:强制执行13个字符的行限制,并用新行替换任何分隔符 //获取所有文本 RichTextBox rtb=(RichTe

我有一个
RichTextBox
(RTB),旁边是一个
DataGrid
(DG)。用户可以将ID列表粘贴到RTB中,以便对其执行一些批量操作。为了让用户知道他们传入RTB的ID是否不在DG中,我想更改文本的颜色

这就是我目前的情况:

private void RichTextBox\u TextChanged(对象发送者,textchangedventargs e)
{
//TODO:强制执行13个字符的行限制,并用新行替换任何分隔符
//获取所有文本
RichTextBox rtb=(RichTextBox)发送方;
TextRange TextRange=新的TextRange(rtb.Document.ContentStart,rtb.Document.ContentEnd);
//分成几行
string[]rtbLines=textRange.Text.Split(new[]{Environment.NewLine},StringSplitOptions.removemptyEntries);
foreach(rtbLines中的字符串行)
{
//删除通讯,但可能会删除其他通讯
行。替换(“,”,”);
//获取ID开头的索引
int startPos=textRange.Text.IndexOf(行);
//这应该是不必要的?
如果(startPos>-1)
{
//获取指向我们找到的文本的指针
TextPointer tp=textRange.Start.GetPositionAtOffset(startPos,LogicalDirection.Backward);
//这应该是不必要的吗?
如果(tp!=null)
{
//获取线路起始位置
text指针tpLine=tp.GetLineStartPosition(0);//有时会抛出StackOverflowException?
//开始下一行
TextPointer testLineEnd=tp.GetLineStartPosition(1);
//如果我们在结尾,则默认为文档的结尾
text指针tpLineEnd=(testLineEnd??tp.DocumentEnd).GetInsertionPosition(LogicalDirection.Backward);
//获取行开始/结束之间的文本范围
TextRange lineText=新的TextRange(tpLine,tpLineEnd);
//投射数据并检查文本是否在其中,以便我们可以检查它
if(unassignedPansListView.ItemsSource!=null&&unassignedPansListView.ItemsSource.Cast().ToList().Any(x=>x.MPAN==line))
{
lineText.ApplyPropertyValue(TextElement.ForegroundProperty,Bruss.Red);
}
其他的
{
lineText.ApplyPropertyValue(TextElement.ForegroundProperty,Bruss.Black);
}
}
}
}
}
问题是,行
TextPointer tpLine=tp.GetLineStartPosition(0)导致堆栈溢出异常
。似乎只有当用户输入一个ID时;粘贴似乎还可以

我认为这是因为
RichTextBox\u TextChanged
事件被反复调用,而粘贴只是一次点击,但我不明白为什么这会导致异常,而不是变得非常缓慢


对于如何实现此功能,也欢迎任何其他建议。我的主要要求是,用户可以粘贴列表,逐个输入,行可以通过编程方式独立着色。

您有例外,因为您在
lineText.ApplyPropertyValue处有递归调用(TextElement.ForegroundProperty
此调用会修改文本。要避免此情况,只需添加标志:

bool changeIsRunning = false;
private void RichTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    if(changeIsRunning)
    {
        return;
    }
    changeIsRunning = true;
    try
    {
      //Put your logic here.
    }
    finally
    {
        changeIsRunning = false;
    }
}

请注意,文本中不仅有可见的文本,还有不可见的元素标记(例如颜色).

是的,确实如此……啊,我明白了,我没有意识到
TextRange.ApplyPropertyValue
也触发了
RichTextBox.TextChanged
事件,但我认为如果它本质上改变了引擎盖下的一些标记元素,那么它是有意义的。