Low Level Element Manipulation
From version 5.2.7 onwards there are included in the RichTextBox several extra methods to enable direct access to the visual elements that make up a RichText document. This new functionality can be used, for example to implement your own HTML serialization or as in the example here to replace certain UIElements without needing to reload the document.
You need to login to Low Level Demo, If you do not have a login you can register for free!
In this example we will show how to replace an image element with another.
<UserControl x:Class="LowLevelRTB.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:liquid="clr-namespace:Liquid"
Width="320" Height="300">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Button x:Name="happyToSad" Grid.Row="0" Margin="0 0 0 4" Content="Convert Happy to Sad!" Click="happyToSad_Click" />
<Button x:Name="sadToCheckbox" Grid.Row="1" Margin="0 0 0 10" Content="Convert Sad to Checkbox!" Click="sadToCheckbox_Click" />
<liquid:RichTextEditor x:Name="richTextEditor" Grid.Row="2" Width="320" />
</Grid>
</UserControl>
As you can see in the above we are using the new Rich Text Editor user control which is basically a wrapped up Liquid RichTextBox with some standard formatting buttons included.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
namespace LowLevelRTB
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
richTextEditor.Html = "<p>Happy <img src=\"images/happy.png\" />... Sad <img src=\"images/unhappy.png\" /></p>";
}
private void happyToSad_Click(object sender, RoutedEventArgs e)
{
Image temp;
BitmapImage source;
UIElement element;
Image newImage;
int i;
// Here we iterate through all the child elements of the RichTextBox and replace smiling images with sad images
for(i=richTextEditor.TextBox.Children.Count-1; i>=0; i--)
{
element = richTextEditor.TextBox.Children[i];
if (element is Image)
{
temp = (Image)element;
source = (BitmapImage)temp.Source;
if(source.UriSource.ToString().EndsWith("/happy.png"))
{
newImage = new Image()
{
Source = new BitmapImage(new Uri("images/unhappy.png", UriKind.Relative)),
Stretch = Stretch.None
};
// As we are swapping an image with another image we could just change the Uri property
// However for this example we want to show how to swap one UIElement with another
richTextEditor.TextBox.SwapElement(element, newImage);
}
}
}
}
private void sadToCheckbox_Click(object sender, RoutedEventArgs e)
{
Image temp;
BitmapImage source;
UIElement element;
CheckBox newCheckbox;
int i;
// Here we iterate through all the child elements of the RichTextBox and replace unhappy images with checkboxes
for (i = richTextEditor.TextBox.Children.Count - 1; i >= 0; i--)
{
element = richTextEditor.TextBox.Children[i];
if (element is Image)
{
temp = (Image)element;
source = (BitmapImage)temp.Source;
if (source.UriSource.ToString().EndsWith("/unhappy.png"))
{
newCheckbox = new CheckBox()
{
Content = "Click Me!",
Cursor = Cursors.Arrow
};
richTextEditor.TextBox.SwapElement(element, newCheckbox);
}
}
}
}
}
}
Using the new SwapElement method we iterate through the RichText document elements replacing certain elements with others.