【问题标题】:How do I mark the cursor to stick in the character position it was at? (WPF RichTextBox)如何将光标标记为停留在它所在的字符位置? (WPF 富文本框)
【发布时间】:2011-03-07 15:45:07
【问题描述】:

我正在使用 WPF 富文本框为文本框中提供的代码创建语法高亮显示。我想让它在我打字时自动调整富文本框,使用线程计时器我重置富文本框的内容。我试图将光标保持在它应该在的位置。在解析过程中我不会丢失任何文本字符(换行符除外)。我不知道如何保持用户在文本中留下的插入符号位置。它默认为文档的末尾。

我尝试将当前插入符号位置存储在文本中,然后在进行更改后将其设置到文档中,但是我收到的错误是“无法将 CaretPosition 设置为 RichTextBox 之外”。所以我将插入符号的位置设置在文档的底部。

WPF、VB.net、.net 框架 4.0

这里是代码。

Public Sub FormatText()

    If IsNothing(rtfContent.Document) Then
        Exit Sub
    End If

    Me.rtfContent.IsEnabled = False
    Me.rtfContent.Refresh()
    Me.Refresh()

    System.Threading.Thread.Sleep(50)

    Dim curRange As TextRange = New TextRange(rtfContent.Document.ContentStart, rtfContent.CaretPosition)

    Dim caretBefore As TextPointer = rtfContent.CaretPosition
    caretBefore = New TextRange(caretBefore, caretBefore.DocumentEnd).Start

    Dim caretBeforeOffset As Integer = rtfContent.Document.ContentStart.GetOffsetToPosition(caretBefore)

    Dim docRange As TextRange = New TextRange(rtfContent.Document.ContentStart, rtfContent.Document.ContentEnd)
    docRange.ClearAllProperties()

    Dim myText As String = docRange.Text
    Dim Lines As List(Of String) = Split(myText, vbCrLf).ToList
    Dim MyBlocks As New List(Of Block)
    Dim count As Integer = 1
    MyVars.Clear()
    myText = ""

    For Each Line In Lines
        If count = Lines.Count Then
            Exit For
        End If

        If Mid(Line, 1, 1) = "$" Then
            Dim words As String() = Split(Line, " ", 2)
            MyVars.Add(words(0))
            myText &= "<Paragraph Margin=""0,0,0,0"" Padding=""0,0,0,2"">" & Line & "</Paragraph>"
        ElseIf Mid(Line, 1, 1) = "#" Then
            myText &= "<Paragraph Margin=""0,0,0,0"" Padding=""0,0,0,2""><Run Foreground=""#FFFFA500"">" & Line & "</Run></Paragraph>"
        Else
            myText &= "<Paragraph Margin=""0,0,0,0"" Padding=""0,0,0,2"">" & Line & "</Paragraph>"
        End If

        count += 1
    Next

    myText = Regex.Replace(myText, "\$(\w*)", "<Run Foreground=""#FFFF0000"">$$$1</Run>")

    For Each var In MyVars
        myText = Regex.Replace(myText, "<Run Foreground=""#FFFF0000"">\" & var & "</Run>", "<Run Foreground=""#FF32CD32"">" & var & "</Run>")
    Next

    myText = myText.Replace("copy", "<Run Foreground=""#FF87CEFA"">copy</Run>")
    myText = myText.Replace("delete", "<Run Foreground=""#FF87CEFA"">delete</Run>")
    myText = myText.Replace("output", "<Run Foreground=""#FF87CEFA"">output</Run>")
    myText = myText.Replace("clear", "<Run Foreground=""#FF87CEFA"">clear</Run>")

    myText = "<FlowDocument PagePadding=""5,0,5,0"" AllowDrop=""True"" NumberSubstitution.CultureSource=""User"" xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">" & myText & "</FlowDocument>"

    Me.rtfContent.Document.Blocks.Clear()
    Me.rtfContent.Document = TryCast(XamlReader.Parse(myText), FlowDocument)

    caretBefore = caretBefore.DocumentStart.GetPositionAtOffset(caretBeforeOffset, LogicalDirection.Forward)

    Try
        Me.rtfContent.CaretPosition = caretBefore
    Catch
        Me.rtfContent.CaretPosition = rtfContent.Document.ContentEnd
    End Try

    Me.rtfContent.IsEnabled = True
    Me.rtfContent.Refresh()
    Me.Refresh()

End Sub

【问题讨论】:

    标签: wpf vb.net richtextbox


    【解决方案1】:

    我有一个想法可能会有所帮助。 Point GetPositionFromCharIndex(int index)PointToClientPointToScreen 函数有帮助吗?您可以存储鼠标光标所在的字符索引,并在生成代码后将其放回提到的位置。你可以找到这些函数的用法here

    【讨论】:

    • 由于某种原因这些功能对我不可用,我使用的是 .net 4.0。
    • 这为我指明了正确的方向,但如果我找不到这些功能,它对我没有帮助。你知道我可以在哪里公开这些功能吗?记住我在 vb.net 中编码。
    猜你喜欢
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 2022-01-06
    • 2011-02-22
    相关资源
    最近更新 更多