Partager via


RichTextBox Overview

Microsoft Silverlight will reach end of support after October 2021. Learn more.

RichTextBox is a control that enables you to display or edit rich content including paragraphs, hyperlinks, and inline images. This topic introduces the RichTextBox control, describes some of its features, and shows examples of how to use it in XAML and code.

This topic contains the following sections.

  • TextBlock, TextBox, or RichTextBox
  • Content Model
  • Creating a RichTextBox
  • Hyperlinks
  • Inline Images or Other Elements
  • Read-Only Mode
  • Traversing the Content
  • Selecting and Formatting Text at Run Time
  • XAML
  • Undo
  • Related Topics

TextBlock, TextBox, or RichTextBox

Silverlight includes three core text controls: TextBlock, TextBox, and RichTextBox. The text control that you use depends on the scenario. The following table lists some scenarios and the recommended control.

Scenario

Recommended Control

Display plain unformatted text.

TextBlock

Display formatted text, paragraphs, hyperlinks, or inline images.

RichTextBox

Enter or edit plain text, such as in a form.

TextBox

Enter or edit formatted text, paragraphs, hyperlinks, or inline images.

RichTextBox

Edit a document, article, or blog that requires formatting, paragraphs, hyperlinks, or inline images.

RichTextBox

Apply character or paragraph formatting.

RichTextBox

Content Model

RichTextBox supports a block-based content model. The content property of RichTextBox is Blocks, which is a collection of Paragraph elements. The Paragraph element can contain elements that are derived from Inline. The following illustration summarizes the content model for RichTextBox and shows how elements derived from Block and Inline fit into this model.

RichTextBox Content Model Diagram

RichTextBox Content Model Diagram

Block Elements

Block elements are classes that inherit from Block. Currently Paragraph and Section derive from Block, but Section is not a part of the document model of RichTextBox.

Block Element

Description

Paragraph

Paragraph is used to group content into a paragraph. The simplest and most common use of Paragraph is to create a paragraph of text. A Paragraph can also contain inline elements.

Inline Elements

Inline elements are classes that inherit from Inline, An inline element is either contained within a block element or another inline element. Inline elements are often used as the direct container of content that is rendered to the screen. For example, a Paragraph (block element) can contain Run (inline element), but the Run actually contains the text that is rendered on the screen. Content in each Paragraph element can contain many types of elements including the following:

Inline Element

Description

Run

Run is used to contain unformatted text. You might expect Run object to be used extensively in content, however, in markup, Run elements are not required to be used explicitly.

Span

Span groups other inline content elements together. No inherent rendering is applied to content within a Span element. That is, content is not formatted if it is placed inside a Span element without any attributes. However, elements that inherit from Span, such as Hyperlink, Bold, Italic, and Underline apply formatting to text.

InlineUIContainer

InlineUIContainer enables UIElement elements (such as Image or Button controls) to be embedded in an Inline content element.

Creating a RichTextBox

Like other Silverlight controls, you can create a RichTextBox in XAML or code. The following shows how to create a RichTextBox in XAML and code.

<!--A RichTextBox with no intial content in it.-->
<StackPanel>
    <RichTextBox/>
</StackPanel>
Private Sub BlankRTB()
    'A RichTextBox with no intial content in it.
    Dim MyRTB As New RichTextBox()
End Sub
private void BlankRTB()
{
    //A RichTextBox with no intial content in it.
    RichTextBox MyRTB = new RichTextBox();
}

The following shows how to create a RichTextBox with a paragraph and some bold text in XAML and code. The VerticalScrollBarVisibility property is set to Auto.

<!--A RichTextBox with intial content in it.-->
<RichTextBox VerticalScrollBarVisibility="Auto">
    <Paragraph>
        A RichTextBox with <Bold>initial content</Bold> in it.
    </Paragraph>
</RichTextBox>
'A RichTextBox with intial content in it.
Private Sub ContentRTB()
    'Create a new RichTextBox with its VerticalScrollBarVisibility property set to Auto.
    Dim MyRTB As New RichTextBox()
    MyRTB.VerticalScrollBarVisibility = ScrollBarVisibility.Auto

    ' Create a Run of plain text and some bold text.
    Dim myRun1 As New Run()
    myRun1.Text = "A RichTextBox with "
    Dim myBold As New Bold()
    myBold.Inlines.Add("initial content ")
    Dim myRun2 As New Run()
    myRun2.Text = "in it."

    ' Create a paragraph and add the Run and Bold to it.
    Dim myParagraph As New Paragraph()
    myParagraph.Inlines.Add(myRun1)
    myParagraph.Inlines.Add(myBold)
    myParagraph.Inlines.Add(myRun2)

    ' Add the paragraph to the RichTextBox.
    MyRTB.Blocks.Add(myParagraph)

    'Add the RichTextBox to the StackPanel.
    MySP.Children.Add(MyRTB)
End Sub
//A RichTextBox with intial content in it.
private void ContentRTB()
{
    //Create a new RichTextBox with its VerticalScrollBarVisibility property set to Auto.
    RichTextBox MyRTB = new RichTextBox();
    MyRTB.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

    // Create a Run of plain text and some bold text.
    Run myRun1 = new Run();
    myRun1.Text = "A RichTextBox with ";
    Bold myBold = new Bold();
    myBold.Inlines.Add("initial content ");
    Run myRun2 = new Run();
    myRun2.Text = "in it.";

    // Create a paragraph and add the Run and Bold to it.
    Paragraph myParagraph = new Paragraph();
    myParagraph.Inlines.Add(myRun1);
    myParagraph.Inlines.Add(myBold);
    myParagraph.Inlines.Add(myRun2);

    // Add the paragraph to the RichTextBox.
    MyRTB.Blocks.Add(myParagraph);

    //Add the RichTextBox to the StackPanel.
    MySP.Children.Add(MyRTB);
}

Elements, such as Paragraph and Bold, determine how the content inside the RichTextBox appears. As a user edits the RichTextBox content, he or she changes this content.

RichTextBox supports hyperlinks. You can use the Hyperlink element to display hyperlinks in a RichTextBox. Hyperlinks provide built-in mouse-over behavior and focus support. Use the NavigateUri property of the Hyperlink element to specify the URL.

NoteNote:

You must set the IsReadOnly property of RichTextBox to true for the Hyperlink element to be active.

The following show shows how to create a RichTextBox with a hyperlink in XAML and code.

<!--A RichTextBox with hyperlink.-->
<RichTextBox IsReadOnly="True">
    <Paragraph>
        Displaying text with <Hyperlink NavigateUri="http://www.msdn.com" TargetName="_blank">hyperlink</Hyperlink>.
    </Paragraph>
</RichTextBox>
'A RichTextBox with hyperlink.
Private Sub HyperlinkRTB()
    'Create a new RichTextBox.
    Dim MyRTB As New RichTextBox()

    ' Create a Run of plain text and hyperlink.
    Dim myRun As New Run()
    myRun.Text = "Displaying text with "
    Dim MyLink As New Hyperlink()
    MyLink.Inlines.Add("hyperlink")
    MyLink.NavigateUri = New Uri("http://www.msdn.com")
    MyLink.TargetName = "_blank"

    ' Create a paragraph and add the Run and hyperlink to it.
    Dim myParagraph As New Paragraph()
    myParagraph.Inlines.Add(myRun)
    myParagraph.Inlines.Add(MyLink)

    ' Add the paragraph to the RichTextBox.
    MyRTB.Blocks.Add(myParagraph)

    'Add the RichTextBox to the StackPanel.
    MySP.Children.Add(MyRTB)
End Sub
//A RichTextBox with hyperlink.
private void HyperlinkRTB()
{
    //Create a new RichTextBox.
    RichTextBox MyRTB = new RichTextBox();

    // Create a Run of plain text and hyperlink.
    Run myRun = new Run();
    myRun.Text = "Displaying text with ";
    Hyperlink MyLink = new Hyperlink();
    MyLink.Inlines.Add("hyperlink");
    MyLink.NavigateUri = new Uri("http://www.msdn.com");
    MyLink.TargetName = "_blank";

    // Create a paragraph and add the Run and hyperlink to it.
    Paragraph myParagraph = new Paragraph();
    myParagraph.Inlines.Add(myRun);
    myParagraph.Inlines.Add(MyLink);

    // Add the paragraph to the RichTextBox.
    MyRTB.Blocks.Add(myParagraph);

    //Add the RichTextBox to the StackPanel.
    MySP.Children.Add(MyRTB);
}

Inline Images or Other Elements

You can display a UIElement, such as an Image or a Button, in a RichTextBox. This enables rich text scenarios, such as displaying content from a chat client and showing emoticons. UI elements are active when the RichTextBox is in read-only mode and inactive in edit mode. For example, they can respond to input and receive focus only when they are in read-only mode. Use the InlineUIContainer tag to add content that is derived from UIElement.

The following shows how to add an image to a RichTextBox in XAML and code.

<RichTextBox>
    <Paragraph>
        Displaying text with inline image
        <InlineUIContainer>
            <Image Source="./flower.jpg" Height="50" Width="50" />
        </InlineUIContainer>            
    </Paragraph>
</RichTextBox>
'A RichTextBox with an image.
Private Sub ImageRTB()
    'Create a new RichTextBox.
    Dim MyRTB As New RichTextBox()

    ' Create a Run of plain text and image.
    Dim myRun As New Run()
    myRun.Text = "Displaying text with inline image"
    Dim MyImage As New Image()
    MyImage.Source = New BitmapImage(New Uri("flower.jpg", UriKind.RelativeOrAbsolute))
    MyImage.Height = 50
    MyImage.Width = 50
    Dim MyUI As New InlineUIContainer()
    MyUI.Child = MyImage

    ' Create a paragraph and add the paragraph to the RichTextBox.
    Dim myParagraph As New Paragraph()
    MyRTB.Blocks.Add(myParagraph)

    ' Add the Run and image to it.
    myParagraph.Inlines.Add(myRun)
    myParagraph.Inlines.Add(MyUI)

    'Add the RichTextBox to the StackPanel.
    MySP.Children.Add(MyRTB)
End Sub
//A RichTextBox with an image.
private void ImageRTB()
{
    //Create a new RichTextBox.
    RichTextBox MyRTB = new RichTextBox();

    // Create a Run of plain text and image.
    Run myRun = new Run();
    myRun.Text = "Displaying text with inline image";
    Image MyImage = new Image();
    MyImage.Source = new BitmapImage(new Uri("flower.jpg", UriKind.RelativeOrAbsolute));
    MyImage.Height = 50;
    MyImage.Width = 50;
    InlineUIContainer MyUI = new InlineUIContainer();
    MyUI.Child = MyImage;

    // Create a paragraph and add the paragraph to the RichTextBox.
    Paragraph myParagraph = new Paragraph();
    MyRTB.Blocks.Add(myParagraph);

    // Add the Run and image to it.
    myParagraph.Inlines.Add(myRun);
    myParagraph.Inlines.Add(MyUI);

    //Add the RichTextBox to the StackPanel.
    MySP.Children.Add(MyRTB);
}

Read-Only Mode

RichTextBox has a read-only mode. You can display rich content in read-only mode. UI elements and hyperlinks in a RichTextBox are active only in read-only mode. For example, they can respond to input and receive focus only when they are in read-only mode. You specify read-only mode by setting the IsReadOnly property of RichTextBox to true. The following shows how to set the IsReadOnly property in XAML and code.

<RichTextBox IsReadOnly="True">
    <Paragraph>
        <Hyperlink NavigateUri="http://www.msdn.com" TargetName="_blank">Hyperlinks</Hyperlink> are enabled in a read-only RichTextBox.
    </Paragraph>
</RichTextBox>
Private Sub ReadOnlyRTB()
    'Create a new RichTextBox.
    Dim MyRTB As RichTextBox = New RichTextBox
    ' Create a Run of plain text and hyperlink.
    Dim myRun As Run = New Run
    myRun.Text = " are enabled in a read-only RichTextBox."
    Dim MyLink As Hyperlink = New Hyperlink
    MyLink.Inlines.Add("Hyperlinks")
    MyLink.NavigateUri = New Uri("http://www.msdn.com")
    MyLink.TargetName = "_blank"
    ' Create a paragraph and add the Run and hyperlink to it.
    Dim myParagraph As Paragraph = New Paragraph
    myParagraph.Inlines.Add(MyLink)
    myParagraph.Inlines.Add(myRun)
    ' Add the paragraph to the RichTextBox.
    MyRTB.Blocks.Add(myParagraph)
    'Add the RichTextBox to the StackPanel.
    MySP.Children.Add(MyRTB)
End Sub
private void ReadOnlyRTB()
{
    //Create a new RichTextBox.
    RichTextBox MyRTB = new RichTextBox();

    // Create a Run of plain text and hyperlink.
    Run myRun = new Run();
    myRun.Text = " are enabled in a read-only RichTextBox.";
    Hyperlink MyLink = new Hyperlink();
    MyLink.Inlines.Add("Hyperlinks");
    MyLink.NavigateUri = new Uri("http://www.msdn.com");
    MyLink.TargetName = "_blank";

    // Create a paragraph and add the Run and hyperlink to it.
    Paragraph myParagraph = new Paragraph();
    myParagraph.Inlines.Add(MyLink);
    myParagraph.Inlines.Add(myRun);

    // Add the paragraph to the RichTextBox.
    MyRTB.Blocks.Add(myParagraph);

    //Add the RichTextBox to the StackPanel.
    MySP.Children.Add(MyRTB);
}

Traversing the Content

You can traverse the content in a RichTextBox by using the TextPointer class and its members. A TextPointer object represents a position in the content of a RichTextBox. The position can either occur between characters in the content, or between the element tags that define the structure for the content. If the position occurs between the characters in the content, then it becomes an insertion position. That is, new content can be added in that position without breaking any semantic rules for the associated content. In practice, an insertion position is anywhere in content where a cursor may be positioned. In most cases, if the position occurs between the element tags that define the structure of the content, then the position is not an insertion position. An example of a valid TextPointer position that is not an insertion position is the position between two adjacent paragraph tags (that is, between the closing tag of the preceding paragraph and the opening tag of the next paragraph).

Some of the operations that you can do by using the TextPointer class include the following:

  • Perform an ordinal comparison of the current position with a second specified position. For more information, see the CompareTo method.

  • Get the TextElement or the RichTextBox that scopes the specified position. For more information, see the Parent property.

  • Translate between TextPointer positions and symbol offsets into content. For more information, see the GetPositionAtOffset method.

  • Perform visual hit testing by translating between a TextPointer position and a Point representing relative coordinates.

  • Find a nearby insertion position, or check whether the current position is an insertion position. For more information, see the GetNextInsertionPosition method and the IsAtInsertionPosition property.

For more information see the TextPointer class.

Selecting and Formatting Text at Run Time

You can format text in RichTextBox at the block-level and inline-level at run time. The following example shows how you can right-align the entire contents of the RichTextBox.

Run this sample

<!--Create a RichTextBox and a Button.-->
<StackPanel>
    <RichTextBox x:Name="MyRTB" Height="100" Width="400" />
    <Button x:Name="MyButton1" Content="Right-Align" Height="30" Width="100" Click="button_Click" />
</StackPanel>
'Right-align the content in RichTextBox on clicking the button.
Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim MyBC As BlockCollection = InlineAssignHelper(MyBC, MyRTB.Blocks)
    For Each b As Block In MyBC
        b.TextAlignment = TextAlignment.Right
    Next
End Sub
Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
    target = value
    Return value
End Function
//Right-align the content in RichTextBox on clicking the button.
private void button_Click(object sender, RoutedEventArgs e)
{
   BlockCollection MyBC = MyRTB.Blocks;
   foreach (Block b in MyBC)
       b.TextAlignment = TextAlignment.Right;               
}

A more common scenario would be where you select a portion of the content and then you apply formatting to the selection. A selection of text in the RichTextBox is represented by the TextSelection class. You can access the currently selected text in the RichTextBox by using its Selection property. To perform operations on the selected text, you can use the GetPropertyValue and ApplyPropertyValue methods. The following example shows how to apply bold, italic, and underline formatting to the selected text.

Run this sample

<!--Create a RichTextBox and three buttons.-->
<StackPanel>
    <RichTextBox x:Name="MyRTB" Width="600" Height="400" />
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
        <Button Content="Bold" Height="30" Margin="2" Width="50" Click="BtnBold_Click" />
        <Button Content="Italic" Height="30" Margin="2" Width="50" Click="BtnItalic_Click" />
        <Button Content="Underline" Height="30" Margin="2" Width="65" Click="BtnUnderline_Click" />
    </StackPanel>
</StackPanel>
'Set Bold formatting to selected content
Private Sub BtnBold_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    If MyRTB IsNot Nothing Then
        If TypeOf MyRTB.Selection.GetPropertyValue(Run.FontWeightProperty) Is FontWeight _
            AndAlso (CType(MyRTB.Selection.GetPropertyValue(Run.FontWeightProperty), FontWeight) = FontWeights.Normal) Then
            MyRTB.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Bold)
        Else
            MyRTB.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Normal)
        End If
    End If
End Sub


'Set Italic formatting to selected content
Private Sub BtnItalic_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    If MyRTB IsNot Nothing Then
        If TypeOf MyRTB.Selection.GetPropertyValue(Run.FontStyleProperty) Is FontStyle _
            AndAlso (CType(MyRTB.Selection.GetPropertyValue(Run.FontStyleProperty), FontStyle) = FontStyles.Normal) Then
            MyRTB.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Italic)
        Else
            MyRTB.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Normal)
        End If
    End If
End Sub


'Set Underline formatting to selected content
Private Sub BtnUnderline_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    If (Not (MyRTB) Is Nothing) Then
        If (MyRTB.Selection.GetPropertyValue(Run.TextDecorationsProperty) Is Nothing) Then
            MyRTB.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, TextDecorations.Underline)
        Else
            MyRTB.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, Nothing)
        End If
    End If
End Sub
//Set Bold formatting to selected content
private void BtnBold_Click(object sender, RoutedEventArgs e)
{
    if (MyRTB != null)
    {
        if (MyRTB.Selection.GetPropertyValue(Run.FontWeightProperty) is FontWeight && ((FontWeight)MyRTB.Selection.GetPropertyValue(Run.FontWeightProperty)) == FontWeights.Normal)
            MyRTB.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Bold);
        else
            MyRTB.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Normal);

    }

}
//<SnippetItalic>
//Set Italic formatting to selected content
private void BtnItalic_Click(object sender, RoutedEventArgs e)
{
    if (MyRTB != null)
    {
        if (MyRTB.Selection.GetPropertyValue(Run.FontStyleProperty) is FontStyle && ((FontStyle)MyRTB.Selection.GetPropertyValue(Run.FontStyleProperty)) == FontStyles.Normal)
            MyRTB.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Italic);
        else
            MyRTB.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Normal);
    }


}

//Set Underline formatting to selected content
private void BtnUnderline_Click(object sender, RoutedEventArgs e)
{
    if (MyRTB != null)
    {
        if (MyRTB.Selection.GetPropertyValue(Run.TextDecorationsProperty) == null)
            MyRTB.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, TextDecorations.Underline);
        else
            MyRTB.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, null);
    }

}

It is also possible to select text programmatically. You can select text in a RichTextBox programmatically by using the Select method. The Select method takes two TextPointer objects as parameters and selects the texts between the two objects. The following code example uses the Select method to programmatically select the last word in a RichTextBox and underline it. In this example, a space character is used as the word boundary. This code example is a part of the larger example used in the TextPointer class.

Run this sample

    'This method underlines the last word in a RichTextBox
    Public Sub UnderlineLastWord()
        Dim EndofContent As TextPointer = MyRTB1.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward)
        Dim currentPointer As TextPointer = EndofContent.GetNextInsertionPosition(LogicalDirection.Backward)
        If (currentPointer Is Nothing) Then
            Return
        End If
        Dim currentChar As String = GetCurrentChar(MyRTB1, currentPointer, LogicalDirection.Backward)

        While ((currentChar <> " ") _
                    AndAlso (currentChar <> ""))
            currentPointer = currentPointer.GetNextInsertionPosition(LogicalDirection.Backward)
            currentChar = GetCurrentChar(MyRTB1, currentPointer, LogicalDirection.Backward)

        End While
        If (currentChar = " ") Then
            MyRTB1.Selection.Select(currentPointer.GetNextInsertionPosition(LogicalDirection.Forward), EndofContent)
        Else
            MyRTB1.Selection.Select(currentPointer, EndofContent)
        End If
        MyRTB1.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, TextDecorations.Underline)
    End Sub

    Private Function GetCurrentChar(ByVal RTB As RichTextBox, ByVal pointer As TextPointer, ByVal direction As LogicalDirection) As String
        Dim nextPointer As TextPointer = pointer.GetNextInsertionPosition(direction)
        If (Not (nextPointer) Is Nothing) Then
            RTB.Selection.Select(pointer, nextPointer)
            If (RTB.Selection.Text.Length <> 0) Then
                Return RTB.Selection.Text(0).ToString
            End If
        End If
        Return ""
    End Function

//This method underlines the last word in a RichTextBox
public void UnderlineLastWord()
{
    TextPointer EndofContent = MyRTB1.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
    TextPointer currentPointer = EndofContent.GetNextInsertionPosition(LogicalDirection.Backward);

    if (currentPointer == null)
        return;

    string currentChar = GetCurrentChar(MyRTB1, currentPointer, LogicalDirection.Backward);

    while (currentChar != " " && currentChar != "")
    {
        currentPointer = currentPointer.GetNextInsertionPosition(LogicalDirection.Backward);
        currentChar = GetCurrentChar(MyRTB1, currentPointer, LogicalDirection.Backward);
    }

    if (currentChar == " ")
        MyRTB1.Selection.Select(currentPointer.GetNextInsertionPosition(LogicalDirection.Forward), EndofContent);
    else
        MyRTB1.Selection.Select(currentPointer, EndofContent);

    MyRTB1.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, TextDecorations.Underline);
}

private string GetCurrentChar(RichTextBox RTB, TextPointer pointer, LogicalDirection direction)
{
    TextPointer nextPointer = pointer.GetNextInsertionPosition(direction);
    if (nextPointer != null)
    {
        RTB.Selection.Select(pointer, nextPointer);
        if (RTB.Selection.Text.Length != 0)
            return RTB.Selection.Text[0].ToString();
    }
    return "";
}

XAML

You can get and set a XAML representation of the content in a RichTextBox by using the Xaml property. The XAML string returned by the Xaml property will only include the following elements:

NoteNote:

Note that The XAML string returned by the Xaml property will not include any UIElement objects that are present in the content. The InlineUIContainer objects will be converted to empty Run objects.

The following table lists various elements and the corresponding properties that are included in the string returned by the Xaml property.

Element

Properties

TextElement

FontSize

FontFamily

Foreground

FontWeight

FontStyle

FontStretch

NoteNote:
The Xaml property only supports attribute values that can be represented as a string. For example, to set the Foreground property, you can only use a SolidColorBrush and not a LinearGradientBrush.

Run

FlowDirection

Text

Section

HasTrailingParagraphBreakOnPaste

Block

TextAlignment

Hyperlink

TargetName

NavigateUri

MouseOverForeground

MouseOverTextDecorations

The following code shows how the XAML is displayed by using the Xaml property.

'Set the xamlTb TextBox with the current XAML of the RichTextBox and make it visible. Any changes to the XAML made 
'in xamlTb is also reflected back on the RichTextBox. Note that the Xaml string returned by RichTextBox.Xaml will 
'not include any UIElement contained in the current RichTextBox. Hence the UIElements will be lost when you 
'set the Xaml back again from the xamlTb to the RichTextBox.

Public Sub btnMarkUp_Checked(ByVal sender As Object, ByVal e As RoutedEventArgs)
    If btnMarkUp.IsChecked.Value Then
        xamlTb.Visibility = System.Windows.Visibility.Visible
        xamlTb.IsTabStop = True
        xamlTb.Text = rtb.Xaml
    Else
        rtb.Xaml = xamlTb.Text
        xamlTb.Visibility = System.Windows.Visibility.Collapsed
        xamlTb.IsTabStop = False

    End If
End Sub
//Set the xamlTb TextBox with the current XAML of the RichTextBox and make it visible. Any changes to the XAML made 
//in xamlTb is also reflected back on the RichTextBox. Note that the Xaml string returned by RichTextBox.Xaml will 
//not include any UIElement contained in the current RichTextBox. Hence the UIElements will be lost when we 
//set the Xaml back again from the xamlTb to the RichTextBox.
public void btnMarkUp_Checked(object sender, RoutedEventArgs e)
{
    if (btnMarkUp.IsChecked.Value)
    {
        xamlTb.Visibility = System.Windows.Visibility.Visible;
        xamlTb.IsTabStop = true;
        xamlTb.Text = rtb.Xaml;
    }
    else
    {
        rtb.Xaml = xamlTb.Text;
        xamlTb.Visibility = System.Windows.Visibility.Collapsed;
        xamlTb.IsTabStop = false;
    }

}

Undo

RichTextBox supports the ability to perform multiple undo operations in response to user actions. In addition, an undo operation can also be reversed, which is called redo. When an undo or redo operation is performed, RichTextBox attempts to set the selection state based on the undo or redo operation.

Undo is supported only if the IsReadOnly property for a RichTextBox is false. Also, programmatic undo operation is not supported.