Search code examples
c#wpfrichtextboxrtf

How to programmatically replace some content of WPF RichTextBox without loosing the formatting?


Question: How can we programmatically replace some text in a WPF RichTextBox without loosing its formatting? In the following code I am clearly not doing something right. My online search gives some relevant suggestions but they seem to be using Winform where RichTextBox has rtf property - such as this one.

Following code correctly replaces text abcd with rstu inside a WPF RichTexBox but it looses the formatting of the RichTextBox as shown in the two images below:

//rtbTest is the name of the RichTextBox
TextRange textRange = new TextRange(rtbTest.Document.ContentStart, rtbTest.Document.ContentEnd);
string oldText = textRange.Text;
string newText = oldText.Replace("abcd", "rstu");
textRange.Text = newText;

Screenshot of RichTextBox BEFORE replacing abcd with rstu:

enter image description here

Screenshot of RichTextBox AFTER replacing abcd with rstu:

As we can see the formatting is lost. The list shown below is not really a formatted numbered list, it probably is just unformatted text (like 1. Item 1 etc.)

enter image description here


Solution

  • It is losing the formatting because you are storing the RTF into a string and the string doesn't keep RTF formatting.

    You can preserve it as following,

    TextRange textRange = new TextRange(rtbTest.Document.ContentStart, rtbTest.Document.ContentEnd);
    string rtf;
    using (var memoryStream = new MemoryStream())
    {
        textRange.Save(memoryStream, DataFormats.Rtf);
        rtf = ASCIIEncoding.Default.GetString(memoryStream.ToArray());
    }
    
    rtf = rtf.Replace("abcd", "rstu");
    
    
    MemoryStream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(rtf));
    rtbTest.SelectAll();
    rtbTest.Selection.Load(stream, DataFormats.Rtf);
    

    enter image description here