Good tip - we don't control when the adorner re-renders, that's done by WPF - but it did make me think that we could cache some of the data.
So if you're using the custom adorner from the other post
http://keyoti.com/support/topic.asp?TOPIC_ID=1619
You can do this as a
startCode:
class CustomRichAdorner : Keyoti.RapidSpell.Wpf.RichErrorAdorner
{
public CustomRichAdorner(RichTextBox adornedElement, int start, int end, Keyoti.RapidSpell.Wpf.IAYTTextBox iayt, Keyoti.RapidSpell.Wpf.UnderlineStyle u, System.Windows.Media.Color c)
: base(adornedElement, start, end, iayt, u, c)
{
IsHitTestVisible = false;
}
<b>
Rect cachedStart, cachedEnd;
TextPointer cachedStartP, cachedEndP;
</b>
protected override void OnRender(DrawingContext drawingContext)
{
if (!startP.HasValidLayout || !endP.HasValidLayout)
{
OnRenderImpossible();
return;
}
if (!active) return;
Rect selectionStartPos_scr = new Rect(0, 0, 0, 0), selectionEndPos_scr = new Rect(0, 0, 0, 0);
<b>
if (cachedStartP!=null && startP.CompareTo(cachedStartP) == 0 /*&& selectionStartPos_scr.X==cachedStart.X && selectionStartPos_scr.Y==cachedStart.Y*/)
{
selectionStartPos_scr = cachedStart;
selectionEndPos_scr = cachedEnd;
}
else
{
selectionStartPos_scr = startP.GetCharacterRect(LogicalDirection.Forward);
selectionEndPos_scr = endP.GetCharacterRect(LogicalDirection.Forward);
cachedStartP = startP;
cachedEndP = endP;
cachedStart = selectionStartPos_scr;
cachedEnd = selectionEndPos_scr;
}
//selectionStartPos_scr = startP.GetCharacterRect(LogicalDirection.Forward);
//selectionEndPos_scr = endP.GetCharacterRect(LogicalDirection.Forward);
</b>
selectionEndPos_scr.Union(selectionStartPos_scr);
drawingContext.DrawRectangle(HighlightFillBrush, HighlightLinePen, selectionEndPos_scr);
}
}
and it is a lot faster with a big text (for example copy paste all of
http://pubs.logicalexpre...9/lpmarticle.asp?id=214 and when run in non-debug mode the typing speed seems entirely acceptable). However, it's only a start and isn't complete.
You'll see as soon as you need to scroll it goes wrong, reason being that it's caching based on if startP is the same from the old value to the new one, but this is only valid provided the text box hasn't scrolled or resized (which would reshuffle the layout). So it needs to detect those 2 events (only) I think, and when they occur invalidate the cache. I haven't got time right now to try it, but thought you might.
I also tried a more foolproof approach of only caching selectionEndPos_scr and using it if the calculated selectionStartPos_scr matched up with a cached one. It worked flawlessly but was obviously slower.
Look forward to hearing what you find.
Jim
-your feedback is helpful to other users, thank you!Evaluation Downloads -
http://keyoti.com/products-your feedback is helpful to other users, thank you!