C# WPF RichTextBox语法突出显示问题

C# WPF RichTextBox语法突出显示问题,c#,wpf,richtextbox,styling,text-styling,C#,Wpf,Richtextbox,Styling,Text Styling,大家好,我一直在开发一个WPF应用程序,它有一个文本编辑器。这个文本编辑器应该在一些标记(关键字)上应用一些样式或颜色,以突出显示它并使其变得明显,,,问题是,我非常努力,但我仍然得到相同的结果,即当用户输入一个关键字后,整个文本的关键字被样式!想象一下,如果你在“C#”中键入“string”关键字,它后面的整个文本将被涂成蓝色 这就是我使用的代码: 静态列表标签=新列表(); 静态列表特殊项=新列表(); 静态字符串文本; #区域导体 静态主窗口() { string[]specialWord

大家好,我一直在开发一个WPF应用程序,它有一个文本编辑器。这个文本编辑器应该在一些标记(关键字)上应用一些样式或颜色,以突出显示它并使其变得明显,,,问题是,我非常努力,但我仍然得到相同的结果,即当用户输入一个关键字后,整个文本的关键字被样式!想象一下,如果你在“C#”中键入“string”关键字,它后面的整个文本将被涂成蓝色

这就是我使用的代码:

静态列表标签=新列表();
静态列表特殊项=新列表();
静态字符串文本;
#区域导体
静态主窗口()
{
string[]specialWords={“string”、“char”、“null”};
标签=新列表(特殊单词);
//我们还想知道所有可能的分隔符,以便添加这些内容。
char[]chrs={
'.',
')',
'(',
'[',
']',
'>',
'0&!(Char.IsWhiteSpace(文本[i-1])| GetSpecials(文本[i-1]))
{
eIndex=i-1;
string word=text.Substring(sIndex,eIndex-sIndex+1);
if(IsKnownTag(word))
{
标签t=新标签();
t、 StartPosition=theRun.ContentStart.GetPositionAtOffset(sIndex,LogicalDirection.Forward);
t、 EndPosition=theRun.ContentStart.GetPositionAtOffset(eIndex+1,LogicalDirection.Backward);
t、 字=字;
m_标签。添加(t);
}
}
sIndex=i+1;
}
}
//这是怎么回事。但是等等。如果这个词是我文本中的最后一个词,我将永远不会高亮显示它,因为我正在寻找分隔符。让我们为这个案例添加一些修复
字符串lastWord=text.Substring(sIndex,text.Length-sIndex);
如果(IsKnownTag(lastWord))
{
标签t=新标签();
t、 StartPosition=theRun.ContentStart.GetPositionAtOffset(sIndex,LogicalDirection.Forward);
t、 EndPosition=theRun.ContentStart.GetPositionAtOffset(eIndex+1,LogicalDirection.Backward);
t、 单词=最后一个单词;
m_标签。添加(t);
}
//我如何把我所有的话和它在列表中的位置。让我们给它上色吧!别忘了退订!文本样式触发TextChanged事件。
txtStatus.TextChanged-=txtStatus\u TextChanged;
对于(int i=0;i
下面是文本更改事件处理程序

private void txtStatus\u TextChanged(对象发送者,textchangedventargs e)
{           
if(txtStatus.Document==null)
返回;
TextRange documentRange=新的TextRange(txtStatus.Document.ContentStart,txtStatus.Document.ContentEnd);
//documentRange.ClearAllProperties();
text=documentRange.text;
//现在,让我们创建导航器来浏览文本并高亮显示它
TextPointer=txtStatus.Document.ContentStart;
while(navigator.CompareTo(txtStatus.Document.ContentEnd)<0)
{
TextPointerContext context=navigator.GetPointerContext(LogicalDirection.Backward);
if(context==TextPointerContext.ElementStart&&navigator.Parent正在运行)
{
CheckWordsInRun((Run)navigator.Parent);
}
navigator=navigator.GetNextContextPosition(LogicalDirection.Forward);
}
}

如果您有任何建议或建议,我们将不胜感激。

您应该突出显示关键字,直到所有文本都被解析,每次运行
时突出显示关键字将影响对
导航器的调用。GetNextContextPosition
,从而导致重复触发textchanged事件等意外错误

高亮显示关键字后,在该关键字后键入的文本将继承该关键字的样式。一种解决方法是在高亮显示关键字之前,对整个文本调用
ClearAllProperties

下面是更新的
txtStatus\u TextChanged
CheckWordsInRun
方法

List<Tag> m_tags = new List<Tag>(); 
internal void CheckWordsInRun(Run theRun) //do not hightlight keywords in this method
{
    //How, let's go through our text and save all tags we have to save.               
    int sIndex = 0;
    int eIndex = 0;

    for (int i = 0; i < text.Length; i++)
    {
        if (Char.IsWhiteSpace(text[i]) | GetSpecials(text[i]))
        {
            if (i > 0 && !(Char.IsWhiteSpace(text[i - 1]) | GetSpecials(text[i - 1])))
            {
                eIndex = i - 1;
                string word = text.Substring(sIndex, eIndex - sIndex + 1);
                if (IsKnownTag(word))
                {
                    Tag t = new Tag();
                    t.StartPosition = theRun.ContentStart.GetPositionAtOffset(sIndex, LogicalDirection.Forward);
                    t.EndPosition = theRun.ContentStart.GetPositionAtOffset(eIndex + 1, LogicalDirection.Backward);
                    t.Word = word;
                    m_tags.Add(t);
                }
            }
            sIndex = i + 1;
        }
    }
    //How this works. But wait. If the word is last word in my text I'll never hightlight it, due I'm looking for separators. Let's add some fix for this case
    string lastWord = text.Substring(sIndex, text.Length - sIndex);
    if (IsKnownTag(lastWord))
    {
        Tag t = new Tag();
        t.StartPosition = theRun.ContentStart.GetPositionAtOffset(sIndex, LogicalDirection.Forward);
        t.EndPosition = theRun.ContentStart.GetPositionAtOffset(text.Length, LogicalDirection.Backward); //fix 1
        t.Word = lastWord;
        m_tags.Add(t);
    }
}

private void txtStatus_TextChanged(object sender, TextChangedEventArgs e)
{
    if (txtStatus.Document == null)
        return;
    txtStatus.TextChanged -= txtStatus_TextChanged;

    m_tags.Clear();

    //first clear all the formats
    TextRange documentRange = new TextRange(txtStatus.Document.ContentStart, txtStatus.Document.ContentEnd);
    documentRange.ClearAllProperties();
    //text = documentRange.Text; //fix 2

    //Now let's create navigator to go though the text, find all the keywords but do not hightlight
    TextPointer navigator = txtStatus.Document.ContentStart;
    while (navigator.CompareTo(txtStatus.Document.ContentEnd) < 0)
    {
        TextPointerContext context = navigator.GetPointerContext(LogicalDirection.Backward);
        if (context == TextPointerContext.ElementStart && navigator.Parent is Run)
        {
            text = ((Run)navigator.Parent).Text; //fix 2
                                 if (text != "")
                CheckWordsInRun((Run)navigator.Parent);
        }
        navigator = navigator.GetNextContextPosition(LogicalDirection.Forward);
    }

    //only after all keywords are found, then we highlight them
    for (int i = 0; i < m_tags.Count; i++)
    {
        try
        {
            TextRange range = new TextRange(m_tags[i].StartPosition, m_tags[i].EndPosition);
            range.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Blue));
            range.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
        }
        catch { }
    }
    txtStatus.TextChanged += txtStatus_TextChanged;
}
List m_tags=new List();
内部void checkwords运行(Run theRun)//不要在该方法中高亮显示关键字
{
//如何,让我们浏览文本并保存所有必须保存的标记。
int-sIndex=0;
int eIndex=0;
for(int i=0;i0&&!(Char.IsWhiteSpace(text[i-1])| GetSpecials(text[i-1]))
{
eIndex=i-1;
string word=text.Substring(sIndex,eIndex-sIndex+1);
if(IsKnownTag(word))
{
标签t=新标签();
t、 StartPosition=theRun.ContentStart.GetPositionAtOffset(sIndex,LogicalDirection.Forward);
t、 EndPosition=theRun.ContentStart.GetPositionAtOffset(eIndex+1,LogicalDirection.Backward);
t、 字=字;
m_标签。添加(t);
}
}
sIndex=i+1;
}
}
//这是怎么回事。但是等等。如果这个词是我文本中的最后一个词,我将永远不会高亮显示它,因为我正在寻找分隔符。让我们为这个案例添加一些修复
字符串lastWord=text.Sub
    private void txtStatus_TextChanged(object sender, TextChangedEventArgs e)
    {           
        if (txtStatus.Document == null)
            return;
        TextRange documentRange = new TextRange(txtStatus.Document.ContentStart, txtStatus.Document.ContentEnd);
        //documentRange.ClearAllProperties();
        text = documentRange.Text;
        //Now let's create navigator to go though the text and hightlight it
        TextPointer navigator = txtStatus.Document.ContentStart;
        while (navigator.CompareTo(txtStatus.Document.ContentEnd) < 0)
        {
            TextPointerContext context = navigator.GetPointerContext(LogicalDirection.Backward);
            if (context == TextPointerContext.ElementStart && navigator.Parent is Run)
            {
                CheckWordsInRun((Run)navigator.Parent);
            }
            navigator = navigator.GetNextContextPosition(LogicalDirection.Forward);
        }
    }
List<Tag> m_tags = new List<Tag>(); 
internal void CheckWordsInRun(Run theRun) //do not hightlight keywords in this method
{
    //How, let's go through our text and save all tags we have to save.               
    int sIndex = 0;
    int eIndex = 0;

    for (int i = 0; i < text.Length; i++)
    {
        if (Char.IsWhiteSpace(text[i]) | GetSpecials(text[i]))
        {
            if (i > 0 && !(Char.IsWhiteSpace(text[i - 1]) | GetSpecials(text[i - 1])))
            {
                eIndex = i - 1;
                string word = text.Substring(sIndex, eIndex - sIndex + 1);
                if (IsKnownTag(word))
                {
                    Tag t = new Tag();
                    t.StartPosition = theRun.ContentStart.GetPositionAtOffset(sIndex, LogicalDirection.Forward);
                    t.EndPosition = theRun.ContentStart.GetPositionAtOffset(eIndex + 1, LogicalDirection.Backward);
                    t.Word = word;
                    m_tags.Add(t);
                }
            }
            sIndex = i + 1;
        }
    }
    //How this works. But wait. If the word is last word in my text I'll never hightlight it, due I'm looking for separators. Let's add some fix for this case
    string lastWord = text.Substring(sIndex, text.Length - sIndex);
    if (IsKnownTag(lastWord))
    {
        Tag t = new Tag();
        t.StartPosition = theRun.ContentStart.GetPositionAtOffset(sIndex, LogicalDirection.Forward);
        t.EndPosition = theRun.ContentStart.GetPositionAtOffset(text.Length, LogicalDirection.Backward); //fix 1
        t.Word = lastWord;
        m_tags.Add(t);
    }
}

private void txtStatus_TextChanged(object sender, TextChangedEventArgs e)
{
    if (txtStatus.Document == null)
        return;
    txtStatus.TextChanged -= txtStatus_TextChanged;

    m_tags.Clear();

    //first clear all the formats
    TextRange documentRange = new TextRange(txtStatus.Document.ContentStart, txtStatus.Document.ContentEnd);
    documentRange.ClearAllProperties();
    //text = documentRange.Text; //fix 2

    //Now let's create navigator to go though the text, find all the keywords but do not hightlight
    TextPointer navigator = txtStatus.Document.ContentStart;
    while (navigator.CompareTo(txtStatus.Document.ContentEnd) < 0)
    {
        TextPointerContext context = navigator.GetPointerContext(LogicalDirection.Backward);
        if (context == TextPointerContext.ElementStart && navigator.Parent is Run)
        {
            text = ((Run)navigator.Parent).Text; //fix 2
                                 if (text != "")
                CheckWordsInRun((Run)navigator.Parent);
        }
        navigator = navigator.GetNextContextPosition(LogicalDirection.Forward);
    }

    //only after all keywords are found, then we highlight them
    for (int i = 0; i < m_tags.Count; i++)
    {
        try
        {
            TextRange range = new TextRange(m_tags[i].StartPosition, m_tags[i].EndPosition);
            range.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Blue));
            range.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
        }
        catch { }
    }
    txtStatus.TextChanged += txtStatus_TextChanged;
}