RichTextBox - how to pass markup codes - wpf

I'm using the RichTextBox to display some readonly text that I have to markup on the fly.
How can I pass markup codes in text to have it rendered by the RichTextBox control?
For example, I'd like to pass this is \cf6 sample \cf1 text to the richtextbox for it to render.
Right now, I build a FlowDocument and add the text value to a run object, but the text gets rendered literally.
RichTextBox fieldLabel = new RichTextBox();
FlowDocument flowDoc = new FlowDocument();
Paragraph myPara = new Paragraph();
Run myRun = new Run(content);
myPara.Inlines.Add(myRun);
flowDoc.Blocks.Add(myPara);
fieldLabel.Document = flowDoc;
I want to see the value in red, but I see the markup instead.
Thanks in advance for any input.

You cant assign RTF text just like that. You need to get that text into a stream and then pass that stream to the RichTextBox.Selection.Load() method. e.g.
MemoryStream stream = new MemoryStream(UTF8Encoding.Default.GetBytes(yourRTFText));
fieldLabel.Selection.Load(stream, DataFormats.Rtf);

You have to apply to the paragraph
// Create a FlowDocument to contain content for the RichTextBox.
FlowDocument myFlowDoc = new FlowDocument();
// Add paragraphs to the FlowDocument.
myFlowDoc.Background = Brushes.LightBlue;
myFlowDoc.Foreground = Brushes.DarkRed;
myFlowDoc.Typography.Capitals = FontCapitals.SmallCaps;
myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 1")));
Paragraph p = new Paragraph(new Run("Paragraph 2"));
p.Foreground = Brushes.Black;
myFlowDoc.Blocks.Add(p);
myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 3")));
RichTextBox myRichTextBox = new RichTextBox();
// Add initial content to the RichTextBox.
myRichTextBox.Document = myFlowDoc;

Related

Can the WPF RichTextBox content be serialized without FontFamily and FontSize?

Much like the editor you see on StackOverflow, I want users to be able to specify that parts of their text should be bold, italic, or underline, but I do not want them to be able to set the font size or family; these need to be inherited from somewhere else in the visual tree.
When placing the WPF RichTextBox control into an empty window and providing a few characters of text, the serialized representation of the rich text always includes the FontFamily. e.g., in LINQPad:
void Main()
{
var window = new Window();
var editor = new RichTextBox();
window.Content = editor;
window.ShowDialog();
var rtf = RtfUtility.ConvertToRtf(editor.Document);
rtf.Dump();
}
I entered "HELLO, WORLD!" into the RichTextBox.
{\rtf1\ansi\ansicpg1252\uc1\htmautsp\deff2{\fonttbl{\f0\fcharset0 Times New Roman;}{\f2\fcharset0 Segoe UI;}}{\colortbl\red0\green0\blue0;\red255\green255\blue255;}\loch\hich\dbch\pard\plain\ltrpar\itap0{\lang1033\fs18\f2\cf0 \cf0\ql{\f2 {\ltrch HELLO, WORLD!}\li0\ri0\sa0\sb0\fi0\ql\par}}}
The RTF serialization code is nothing special:
var range = new TextRange(document.ContentStart, document.ContentEnd);
using (var stream = new MemoryStream())
{
range.Save(stream, DataFormats.Rtf);
stream.Position = 0;
using (var reader = new StreamReader(stream, Encoding.UTF8))
return reader.ReadToEnd();
}
The serialized representation references both Times New Roman and Segoe UI, but this is undesirable.
Is it possible to present rich text and inherit the font family and size from elsewhere, as well as serialize it without these properties?
I suppose an alternative is to set FontFamily and FontSize to whatever I want each time the text is deserialized -- but that just seems hacky. I'd also be open to an entirely different solution that does not involve RichTextBox, if that's feasible.
FlowDocument assumes Sergoe UI as default font. This font is in the style for FlowDocument objects.
To change this:
editor.Document.FontFamily = new FontFamily("Times New Roman");
editor.Document.FontSize = 12;
You can also create a style for all FlowDocuments using xaml declarations in App.xaml or programmatically, for each FlowDocument:
var style = new Style(typeof(FlowDocument));
style.Setters.Add(new Setter(FlowDocument.FontFamilyProperty, new FontFamily("Times New Roman")));
style.Setters.Add(new Setter(FlowDocument.FontSizeProperty, 12));
editor.Resources.Add(typeof(FlowDocument), style)
When creating style for a paragraph (new Style(typeof(Paragraph))) you can also change each individual paragraph's settings.
Unfortunately serialization saves FlowDocument's resources and all settings which are not inherited.
You can use a textrange:
TextRange tr2 = new TextRange(mergedDocument.ContentStart, mergedDocument.ContentEnd);
tr2.ApplyPropertyValue(Span.FontFamilyProperty, font);
tr2.ApplyPropertyValue(Span.FontSizeProperty, "24");
tr2.ApplyPropertyValue(List.FontFamilyProperty, font);
tr2.ApplyPropertyValue(List.FontSizeProperty, "24");

Place UIElement and Text in same line in RichTextbox

How to place text and Button in a same line in WPF Richtextbox?
In the image below some texts and a button control are placed in a richtextbox.
I want some texts to be placed before and after the button in the same line.
Is it possible to define some width to the blockuicontainer or a wayout to achieve the same?
What I want is:
I have added a FlowDocument to the RichTextBox and a Paragraph to the FlowDocument.
Sample code is:
Paragraph para = new Paragraph();
FlowDocument fd = new FlowDocument();
fd.Blocks.Add(para);
txtExpression.Document = fd;
para.Inlines.Add(new Button() { Content = "Hello!" });

The content copied from a richtextbox is not getting saved in my database

Am trying to copy the content of a Richtextbox to another Richtextbox using the below code.
FlowDocument doc = RTB1.Document;
RTB1.Document = new FlowDocument();
RTB2.Document = doc;
But the copied line disappears if i try to save the screen where the RichTextBox(RTB2) is there.
Any help on this will be greatful.
In your code RTB1.Document = new FlowDocument(); will asign a new FlowDocument value to the RTB1.that's why the copied line disappears.
Try this
first you need to include the namespace and add the code below
using System.IO;
using System.Windows.Markup;
MemoryStream ms = new MemoryStream();
XamlWriter.Save(RTB1.Document, ms);
ms.Seek(0, SeekOrigin.Begin);
RTB2.Document = XamlReader.Load(ms) as FlowDocument;
After copying the content from one RichTextBox to another the content used to disappear because the focus was not coming back to the copied RichTextBox.
So the solution i used was to set the focus of RichTextBox2 after copying.
FlowDocument doc = RTB1.Document;
RTB1.Document = new FlowDocument();
RTB2.Document = doc;
RTB2.Focus();

C# String in RichTextBox Wpf

I have the following question:
I have a class Question which has a property BodyString of the type String.
How do I put this String in a Wpf-RichTextBox?
yourRichTextBox.AppendText(BodyString);
From this answer:
The WPF RichTextBox has a Document property for setting the content a la MSDN:
// Create a FlowDocument to contain content for the RichTextBox.
FlowDocument myFlowDoc = new FlowDocument();
// Add paragraphs to the FlowDocument.
myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 1")));
myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 2")));
myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 3")));
RichTextBox myRichTextBox = new RichTextBox();
// Add initial content to the RichTextBox.
myRichTextBox.Document = myFlowDoc;
You can just use the AppendText method though if that's all you're after.
Hope that helps.

How to get a WPF rich textbox into a string

I saw how to set a WPF rich text box in RichTextBox Class.
Yet I like to save its text to the database like I used to, in Windows Forms.
string myData = richTextBox.Text;
dbSave(myData);
How can I do it?
At the bottom of the MSDN RichTextBox reference there's a link to How to Extract the Text Content from a RichTextBox
It's going to look like this:
public string RichTextBoxExample()
{
RichTextBox myRichTextBox = new RichTextBox();
// Create a FlowDocument to contain content for the RichTextBox.
FlowDocument myFlowDoc = new FlowDocument();
// Add initial content to the RichTextBox.
myRichTextBox.Document = myFlowDoc;
// Let's pretend the RichTextBox gets content magically ...
TextRange textRange = new TextRange(
// TextPointer to the start of content in the RichTextBox.
myRichTextBox.Document.ContentStart,
// TextPointer to the end of content in the RichTextBox.
myRichTextBox.Document.ContentEnd
);
// The Text property on a TextRange object returns a string
// representing the plain text content of the TextRange.
return textRange.Text;
}

Resources