1
votes

I'm currently developing a very simple app with very basic syntax highlighting in a RichTextBox.

It works almost fine. What I'm doing is:

  • Lookup a list of predefined regex if one or more matches.
  • Select the match, applying the right style to the selection.
  • Then replace the cursor where it initially was.

This method gets triggered on every KeyUp event. And it makes a LOT of flickering.

So my question is: how could I subtly highlight the text that I type without any flickering? This editor will never contain thousands lines of text, maybe about a hundred max so I don't need any very optimized solution yet.

I tried some of the solutions proposed on other posts, but nothing interesting worked. And I don't want to use another component from another library -- I wanted to do it myself for learning purposes.

2
Have you tried making a copy of it with RenderTargetBitmap, putting the copy of it in the same place in the visual tree, removing it from the visual tree, doing your manipulations, putting it back in the visual tree, and then removing the copy?Ed Bayiates

2 Answers

2
votes

The way I did it was to wait til typing stopped, and then do the highlighting once. This was the basic logic:

  • with each keyup (or testchange, etc), set the "last change" time, and, queue a background task (QueueUserWorkItem)

  • In the WaitCallback for the background thread, wait 750ms via System.Threading.Thread.Sleep(). When the sleep finishes, check the "last change" time. Is it less than 750ms ago? If so, the user is still typing, so,... nothing to do. Just exit the method.

  • if the last change time is more than 750ms ago, then the user has stopped typing. In other words, no changes have occurred in the past 750ms of real time. So, do the highlighting. Remember that you need to do UI updates on the UI thread. That means checking this.InvokeRequired in a WinForms app, or this.Dispatcher.CheckAccess() in WPF, before applying formatting.

0
votes

I decided to try something and it worked amazingly!

I'm highlighting one line at a time. So when the keyUp gets triggered I only parse the selected line. So NO flickering!

And at the startup I made a HighlightLines() method that loop through the lines and call my HighlightLine(lineIndex) method.

I'll try to mix my solution with Cheeso's and I guess it'll make something awesome!

Thanks