What I'm doing here is loading a file into a RichTextBox as an
XamlPackage
. Once loaded, I calculate the number of lines per page (NoLinesPerPage) (from preset top/bottom margins and target paper height).
The particular values I'm working with give me a number of 36 lines per page.
Now, I want to draw lines at soft page breaks (every 36 lines), so I'm trying to get the GetCharacterRect(LogicalDirection.Forward).Y values for the first character of every 36 lines (Y values which I then pass to a set of
RichTextBox
Adorner
s), to the end of the FlowDocument.
The problem is, when I load my
FlowDocument
and run the subroutine to go through every 36 lines, I'm not getting them all the way through to the end. Only about the first 75% or so.
My routine for getting the
TextPointer
s at each 36th line is thus:
Private Sub UpdatePageLinePositions()
Dim PageLinePointers As New List(Of TextPointer)
Dim tpointer As TextPointer = Dox.Document.ContentStart.GetLineStartPosition(0)
Dim ypoint As Integer = 0
Dim charrect As Rect = Nothing
Dim nextpagept As TextPointer = tpointer
Dim lastpage As Boolean = False
While lastpage = False
Dim pcount As Integer = 0
nextpagept = nextpagept.GetLineStartPosition(CurrDoc.NoLinesPerPage, pcount)
If pcount = CurrDoc.NoLinesPerPage Then
PageLinePointers.Add(nextpagept)
Else
lastpage = True
End If
End While
MsgBox(PageLinePointers.Count)
For Each plp As TextPointer In PageLinePointers
charrect = plp.GetCharacterRect(LogicalDirection.Forward)
AdornerLayer.GetAdornerLayer(Dox).Add(New LineAdorner(Dox, charrect.Y))
Next plp
(I end the loop if
pcount
is less than the skipped number of lines (which means it is at the end of the document).
Now, for my test document, I should come up with 19 pages (18 adorners), but when I load the document I only get 12, or sometimes 13 (the last ~25% of the document has no visible adorners, and my
PageLinePointers
list count is only 12 or 13.
However, if I don't comment out the
MsgBox(pcount)
within the
While
loop, so that the value "36" gets messaged 18 times, then I get all 18
PageLinePointers
, and all 18 page line adorners are visible on my FlowDocument.
What I have tried:
So, I guessed this must be a threading issue, it's looping too fast and reaching the end (lastpage=true) before the last few
nextpagept.GetLineStartPosition
calls are made, and the returned values actually get added to the List.
So I tried a running as a synchronous Task:
Dim mytask As New Task(Sub() nextpagept = nextpagept.GetLineStartPosition(CurrDoc.NoLinesPerPage, pcount))
mytask.RunSynchronously()
inside the Loop, but it still stops at the 12th or 13th loop, failing to get all of the page line textpointers.
I also tried with a Dispatcher
Application.Current.Dispatcher.Invoke(Sub() nextpagept = nextpagept.GetLineStartPosition(CurrDoc.NoLinesPerPage, pcount))
with the same result.
But in all cases, if I have the interruption of a MsgBox inserted in the loop, it gets all 18 pages.
What am I failing to do correctly here?