Hello Telerik,
in the WPF RadRichTextBox I have this example text:
"Hello my friend, everything is great today".
Now the user selects only the word 'great' and I want to increase the fontsize +2 only for this word.
My code looks like this:
private async Task<bool> FormatIncreaseFont()
{
await Task.Delay(1);
double newFontSize = 0;
var boxes = RichTextBox.Document.Selection.GetSelectedBoxes();
foreach (var box in boxes)
{
//AssociatedDocumentElement is wrong.
Span span = box.AssociatedDocumentElement as Span;
if (span != null)
{
newFontSize = (newFontSize == 0) ? Math.Round(Unit.DipToPoint(span.FontSize), 0) + 2 : newFontSize;
//span.FontSize is also wrong
span.FontSize = Unit.PointToDip(newFontSize);
}
}
RichTextBox.UpdateEditorLayout();
return true;
}
AssociatedDocumentElement is the span where the InlineLayoutBox lives in, so I get the wrong font size.
Also I am changing the font size of the whole span, not only the InlineLayoutBox .
My questions are:
1.) How do I get the current font size of the InlineLayoutBox ("great").
2.) How do I then change the font size only for this InlineLayoutBox ("great").
Thank you!
4 Answers, 1 is accepted
Hi Max,
To change the font size, you should use the ChangeFontSize method, the FontSize property should be used before the span is added to the document. And this way you do not need to update the entire layout. You can get the font size with your approach:
private void RadButton_Click(object sender, RoutedEventArgs e)
{
var boxes = radRichTextBox.Document.Selection.GetSelectedBoxes();
Span span = boxes.First().AssociatedDocumentElement as Span;
var fontSize = Unit.DipToPoint(span.FontSize);
radRichTextBox.ChangeFontSize( Unit.PointToDip(fontSize + 2));
}
I have tested this and it works on my side (see attached).
I hope this helps. Should you have any other questions do not hesitate to ask.
Regards,
Dimitar
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.
Thank you Dimitar,
your solution works for one selected word - and this is exactly, what I have been asking for. So this is great!
Now, if you select two words, every selected word should grow +2 RELATIVE to its original size.
That doesn't work, as you can see in the attached gif.
My current code looks like this:
private async Task<bool> FormatIncreaseFont()
{
await Task.Delay(1);
double newFontSize = 0;
RichTextBox.Document.Selection.GetSelectedBoxes().ToList().ForEach(box =>
{
if (box != null)
{
Span span = box.AssociatedDocumentElement as Span;
if (span != null)
{
newFontSize = (newFontSize == 0) ? Math.Round(Unit.DipToPoint(span.FontSize), 0) + 2: newFontSize;
RichTextBox.ChangeFontSize(Unit.PointToDip(newFontSize));
}
}
});
RichTextBox.UpdateEditorLayout();
return true;
}
My thoughts on this is, that "RichTextBox.ChangeFontSize" always changes the font size of the complete selection.
My questions are:
1.) Would it be possible to get all selected boxes and then programmatically select each word one by one?
2.) Or do you have a smarter solution?
Thank you!
Hello Dimitar,
I needed some hours to understand, how the RadRichTextBox selection works.
With the following code you can select one, many or many individual words.
The font size of each word will be increased individually AND relative to its orginal size.
This is done by selecting each InlineLayoutBox. Look at the gif in the attachment.
CODE:
private async Task<bool> FormatIncreaseFont()
{
await Task.Delay(1);
List<InlineLayoutBox> boxes = null;
SelectionRange currentSelection = null;
List<SelectionRange> backupUserSelections = new List<SelectionRange>();
try
{
boxes = RichTextBox.Document.Selection.GetSelectedBoxes().ToList();
currentSelection = RichTextBox.Document.Selection.Ranges.First();
RichTextBox.Document.Selection.Ranges.ToList().ForEach(r =>
{
backupUserSelections.Add(new SelectionRange() { StartPosition = r.StartPosition, EndPosition = r.EndPosition });
});
}
catch
{
boxes = null;
currentSelection = null;
backupUserSelections = null;
}
if (boxes == null || currentSelection == null || backupUserSelections == null) return true;
boxes.ForEach(box =>
{
if (!string.IsNullOrWhiteSpace(box.Text))
{
//Every InlineLayoutBox is individually selected.
DocumentPosition selectionStart = currentSelection.StartPosition;
DocumentPosition selectionEnd = currentSelection.EndPosition;
selectionStart.MoveToInline(box, 0);
selectionEnd.MoveToInline(box, box.PositionsCountInBox);
RichTextBox.Document.Selection.Clear();
RichTextBox.Document.Selection.AddSelectionStart(selectionStart);
RichTextBox.Document.Selection.AddSelectionEnd(selectionEnd);
InlineLayoutBox selectedBox = RichTextBox.Document.Selection.GetSelectedBoxes().FirstOrDefault();
if (selectedBox != null)
{
Span span = selectedBox.AssociatedDocumentElement as Span;
if (span != null)
{
//Increase the fontsize of each InlineLayoutBox individually
double newFontSize = Math.Round(Unit.DipToPoint(span.FontSize), 0) + 2;
RichTextBox.ChangeFontSize(Unit.PointToDip(newFontSize));
}
}
}
});
RichTextBox.Document.Selection.Clear();
//Once we are done, we have to restore all original selections,
//so that the user can do other formatting operations on the selection.
backupUserSelections.ForEach(userSelection =>
{
DocumentPosition selectionStart = userSelection.StartPosition;
DocumentPosition selectionEnd = userSelection.EndPosition;
RichTextBox.Document.Selection.AddSelectionStart(selectionStart);
RichTextBox.Document.Selection.AddSelectionEnd(selectionEnd);
});
RichTextBox.UpdateEditorLayout();
return true;
}
Greetings!
Hello Max,
I am glad that you have found a solution for your case. And thank you for sharing it with the community.
Do not hesitate to contact us if you have other questions.
Regards,
Dimitar
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.