WPF RichTextBox Control, How To Find All Italicized Words - wpf

How can you loop through all the "words" (spaces deliminate words) in an RTB (WPF Control) to see which ones are italicized?
thanks

Well, your task seems to be a quite complicated one.
The contents of a RichTextBox is a FlowDocument which can be found at the property Document. The FlowDocument, in turn, consists of several Blocks.
Each of the Blocks can be a Paragraph, a Section, a Table etc. You'll need to analyze each of them separately.
For the Paragraph, it consists of several Inlines, each of them can be a Span, which in turn may be an Italic. The Italic represents italicized text. The Italic can, in turn, have other inlines, containing other Spans (for example, Hyperlinks, which you may or may not want to include into your result).
You you basically need to traverse all the structure recursively and peek the text from your Italics. A special case may be the words where only a part is italicized, you'll need to have a strategy for them.
I am unaware of any easier methods to achieve what you want. HTH.
Edit:
Perhaps an easier alternate solution would be to traverse all the text using TextPointer from the beginning (richTextBox.Document.ContentStart), switching to the next position with position.GetNextContextPosition(LogicalDirection.Forward), and testing if your current position is inside an Italic using position.Parent. You should however care that Italic can be a non-immediate parent, so you'll perhaps need to traverse several parents upwards. Disclaimer: I did never try this idea in my code.

TextPointer tp = RTB.Document.ContentStart;
TextRange word = WordBreaker.GetWordRange(tp);
while (word.End.GetNextInsertionPosition(LogicalDirection.Forward) != null)
{
if (word.GetPropertyValue(TextElement.FontStyleProperty).ToString() == "Italic")
{
}
word = WordBreaker.GetWordRange(word.End.GetNextInsertionPosition(LogicalDirection.Forward));
}
}
with WordBreaker class from
Link

Related

How to find the TextRange of the Nth word in a WPF RichTextBox?

Lets say I have a RichTextBox (WPF) of 1000 words (English). Some words will be Bold, Underlined, Italic, and of different FontSizes. In other words, there are many element tags embedded within the FlowDocument.
Without knowing what the word is, how can I completely select the 13th word -- and only the 13th word, even if it has embedded element tags (say some characters are Bold, or Underlined, etc.)?
(I have not found any solution to this with Google and I am still finding the RichTextBox a rather difficult control to use).
Example: "This is a test."
Given: 3
Result: The TextRange of the word "test".
Any suggestions or ideas will be most appreciated.
TIA
Edit. It seems a loop will be needed :(. Anyway, this blog post was most helpful in answering this problem:Navigate Words in RichTextBox
Not very sure what you mean by embaded element tags, I gave it a try and here is how I did it :
string a = new TextRange(rtb.Document.ContentStart,
rtb.Document.ContentEnd).Text;
var b = a.Split(' ');
string On13th = b[12];
Let me know if I am not clear or you intended to achieve something else.

Highlight line(s)/characters in WPF

Scenario
I am currently developing an application. Within this application, I have a TextBox/RichTextBox. I have not decided on the control yet. Within this control, there will be a few paragraphs of text.
Problem
I want to be able to highlight a range of lines, or particular characters within that line, using two given numbers. What would the easiest way to do this be?
Use RichTextBox. You can't use TextBox, that is because TextBox has only one style applied to all text.
Use the TextRange.ApplyPropertyValue method. A TextRange is specified by its starting and ending position, which are two TextPointer.
Something like this
var startingPos = RichTextBox1.ContentStart.GetPositionAtOffset(n1, LogicalDirection.Forward);
var endingPos = startingPos.GetPositionAtOffset(n2 - n1, LogicalDirection.Forward);
var textrange = new TextRange(startingPos, endingPos);
textrange.ApplyPropertyValue(TextElement.BackgroundProperty, Brushes.DarkRed);
You have to carefully calculate the offsets of the starting and ending positions, taking linebreaks into account.

RichTextBox SelectionFont is unexpectedly *not* null

I'd like to change the font size of a chunk of RTF without erasing the bold / italic / underline formatting (an issue similar to the one in this question). The accepted answer is to modify the selection of the text box until the SelectionFont propery is null in order to find runs of consistently formatted text which can be modified individually. Sounds reasonable. However the actual behavior of the RichTextBox control seems to be inconsistent with the documentation.
In the documentation for RichTextBox.SelectionFont MSDN states:
If the current text selection has more than one font specified, this
property is null.
However, this code which uses mixed bold / regular text doesn't behave as you'd expect:
var rtb = new RichTextBox {
Rtf = #"{\rtf1 This is \b bold\b0.}"
};
rtb.SelectAll();
// Now you'd expect rtb.SelectionFont to be null,
// but it actually returns a Font object
Is there any other reliable way of formatting the text so that I can change the font size without clobbering the other formatting. (Manipulating the RTF directly is OK, I'm not absolutely set on using WinForms to achieve this).
I've given up on trying to go through Winforms to fix this. As I'm applying the change to a whole document (rather than just one portion), it turns out that it's not too hard to modify the RTF directly.
In this case I'm interested in the font size, which is represented by the \fs command. So to replace all the 8.5pt text with 10pt text, you can replace \fs17 with \fs20. (Yes, RTF font sizes come in units of half a point, apparently).
This seems to work well enough, although it does feel like one of those "let's mangle our HTML using regular expressions" type solutions, so I'm not convinced that it's very robust.
Take a look at this:
Changing font for richtextbox without losing formatting
I think it's the same issue. LarsTech's solution is working perfectly for me.

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?
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:
Create a subclass of UIElement
Get the Style with ControlTemplate for the Richtextbox and add it to App.xaml
Add an instance of your subclassed UIElement within the inner Panel of the Scrollviewer from the RichTextBox ControlTemplate
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
In your UIElement subclass, you iterate through characters of the document
Draw a symbol in your Adorner for each space and LineBreak you encounter
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:
Create a Custom Adorner
Decorate the RTBox with the custom Adorner
From the Adorner, you should be able to access the Child RTBox
In your UIElement subclass, you iterate through characters of the document
Draw a symbol in your UIElement for each space and LineBreak you encounter
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.
You can try insert near LTR/RTL visible glyph instead of replace that.
Store all of the values as their special characters. It sounds like your printing functions need to handle a) what kind of output the user wants, b) interpret your data array/massive string of characters and spit out the values with regard to what the user wants to see. You don't give too many details on how your things are stored but this would be a very reasonable way to go about things.

Bullets and Numbering in Silverlight

I'm looking for some comprehensive library for Silverlight on bullets/numbering. I've found a few, like Vector Light's RTB control, but most are lacking extended features of bullets/numbering that word processing programs have, like having the First Line Indent of a great value than the Hanging Indent (e.g. first line indent is 1 inch and hanging indent is .5 inch). Another example is customizing the size of the bullet/number Anyone know of good libaries for this for Silverlight?
Check out the ordered/unordered list controls explained in this link. You can extend its functionality to acheive what you intend to do. I have used it to show hierarchical data using nested lists and found it fairly easy to modify it to my needs.
that implementation works for read-only content only.
What if you need to apply bullets/numbering/indent to selected-text in a RichTextBox?
You have to programmatically find Paragraph elements inside selected-text and insert the corresponding character (bullet or number of tab) at the start of each Paragraph element.
Check out here for detailed explanation: http://www.codeding.com/?article=22

Resources