Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render whitespaces as dots in WPF RichTextBox?

I need the way to render regular space, nonbreaking space and some other formatting characters (like left-to-right mark) like MS Word renders them, when you choose to show non-printable characters.

I tried two approaches:

1) Replace characters with rarely used characters. It works, but in this case we loose "nonbreaking" behavior of nonbreakable space (and LTR and RTL marks also stop working)

2) Use the custom font

It allows to preserve special behavior of nonbreaking space and LTR/RTL marks, but for some strange reason WPF renders nonbreaking space with usual space glyph.

WinForms RichTextBox renders text with the same font correctly.

This problem could be solved with applying different font with different space glyph for spaces and nonbreaking spaces, but LTR and RTL marks are not rendered at all even if I add glyph for them.

Have you any ideas how I could render that characters with visible glyph preserving their "LTR", "RTL", "nonbreaking" behavior?

like image 644
Mikhail_K Avatar asked Jun 14 '12 04:06

Mikhail_K


1 Answers

I didn't try anything similar until now, but I can think of two options:

Warning -> I didn't try it out

The first method:

  1. Create a subclass of UIElement
  2. Get the Style with ControlTemplate for the Richtextbox and add it to App.xaml
  3. Add an instance of your subclassed UIElement within the inner Panel of the Scrollviewer from the RichTextBox ControlTemplate
  4. Make the RTBox available to a dependency property in your class via DataBinding in the ControlTemplate (if possible) or any other way that does the job
  5. In your UIElement subclass, you iterate through characters of the document
  6. Draw a symbol in your Adorner for each space and LineBreak you encounter
  7. Get the Rect of a character at a specific position with the RichTextBox. Use this rect for placing the symbols.

The advantage of this Method is that you have a clean separation and don't need to subclass the RTFBox, but you won't be able manipulate the width of the spacing to make room for larger symbols. Also, other developers need to know that they need that Style in order to gain that functionality.

The second method:

  1. Create a Custom Adorner
  2. Decorate the RTBox with the custom Adorner
  3. From the Adorner, you should be able to access the Child RTBox
  4. In your UIElement subclass, you iterate through characters of the document
  5. Draw a symbol in your UIElement for each space and LineBreak you encounter
  6. I remember that there is a possibility to get the Rect of a character at a specific position with the RichTextBox. Use this rect for placing the symbols.

It's also without subclassing the RTBox. You also can't adjust the spacing. In contrast to method 1, other developers will immediatly recognize that this functionality has been added. The one disadvantage is that you will have to handle scrolling too.

like image 145
Alex Maker Avatar answered Oct 06 '22 08:10

Alex Maker