2011-03-07 31 views
1

我正在使用WPF richtextbox爲文本框中提供的代碼創建語法高亮顯示。我想讓它在我鍵入時自動調整富文本框,使用線程計時器重設富文本框的內容。我試圖將光標保持在假定的位置。在解析過程中,我不會丟失任何文本字符(換行符除外)。我不知道如何將插入的位置保留在用戶留在文本中的位置。它默認爲文檔的結尾。如何標記光標以保持它所處的字符位置? (WPF RichTextBox)

我嘗試在文本中存儲當前插入符的位置,然後在進行更改後將其設置爲文檔,但是我收到的錯誤是「無法將CaretPosition設置爲在RichTextBox之外」。因此,我將插入位置設置爲文檔底部。

WPF,VB.net,.net Framework 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 

回答

1

我有一個想法可能會有所幫助。 Point GetPositionFromCharIndex(int index),PointToClientPointToScreen功能是否有幫助?您可以存儲鼠標光標所在的字符索引,並在生成代碼後將其放回到所提到的位置。你可以找到這些功能的使用here

+0

由於某些原因,這些功能不適用於我,我正在使用.net 4.0。 – JustinKaz 2011-03-07 17:19:06

+0

這使我指出了正確的方向,但如果我找不到這些功能,它並不會幫助我。你知道我可以在哪裏獲得這些功能嗎?請記住我在vb.net編碼。 – JustinKaz 2011-03-16 12:22:48

相關問題