In this Post, we’ll build a basic WPF RichTextBox Editor, which lets users create and edit rich text documents. The application will support features such as formatting text (bold, italic, underline), changing fonts, saving, and loading text, rtf, html and image files.
Build A WPF RichTextBox Editor Application
Getting Started
Windows Presentation Foundation (WPF) provides powerful tools to build modern desktop applications for Windows. One of the controls that developers frequently use when building text editing applications is the RichTextBox. This control allows users to input, format, and save rich text content.
Here we will see how to build a editor application in WPF using XAML and C# where we will load files (like Text, RTF, HTML and Image), format text and save RichTextBox content to file.
Prerequisites
- Visual Studio 2022 or later
- .NET 6+ SDK or .NET Framework (e.g., 4.8)
- Knowldge of C# Language
- Basic understanding of WPF/XAML
Demonstration
Create the WPF Project- Launch Visual Studio from the Start Menu or Desktop shortcut.
- Click "Create a new project" on the start screen.
- In the search box, type WPF.
- Choose WPF App (.NET Framework) template
- Click Next.
- Enter project name, e.g., RichTextEditor
- Choose where to save it.
- Click Create.
<Window x:Class="WPFRichtextbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Name="gdgrid">
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu>
<MenuItem Header="File">
<MenuItem Header="Open" Click="Load_Click"/>
<MenuItem Header="Save" Click="Save_Click"/>
</MenuItem>
<MenuItem Header="Format Text">
<MenuItem Header="Bold" Click="Bold_Click"/>
<MenuItem Header="Italic" Click="Italic_Click"/>
<MenuItem Header="Underline" Click="Underline_Click"/>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Color" VerticalAlignment="Center" Margin="0,2,5,2"/>
<ComboBox Text="Black" Width="100" IsEditable="True" IsReadOnly="True" SelectionChanged="ComboBox_SelectionChanged">
<ComboBoxItem>Black</ComboBoxItem>
<ComboBoxItem>Red</ComboBoxItem>
<ComboBoxItem>Blue</ComboBoxItem>
<ComboBoxItem>Yellow</ComboBoxItem>
</ComboBox>
</StackPanel>
</MenuItem.Header>
</MenuItem>
</Menu>
<RichTextBox Grid.Row="1" Name="richTextBox" >
<FlowDocument>
<Paragraph >
This is a WPF RichTextBox Editor Demonstration .
</Paragraph>
</FlowDocument>
</RichTextBox>
</Grid>
</Window>
In MainWindow.xaml
, replace the existing content with the above XAML code and the following features are added to UI.
- Open/Save buttons to load and save RTF files
- Bold, Italic, Underline formatting options
- Font color selection
using Microsoft.Win32;
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace WPFRichtextbox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//this.AddRichtextbox();
}
void AddRichtextbox()
{
RichTextBox richTextBox = new RichTextBox();
richTextBox.Margin = new Thickness(10, 0, 10, 10);
this.gdgrid.Children.Add(richTextBox);
Grid.SetRow(richTextBox, 1);
richTextBox.Document.Blocks.Clear();
// Create a FlowDocument to contain content for the RichTextBox.
FlowDocument myFlowDoc = new FlowDocument();
// Create a Run of plain text and some bold text.
Run myRun = new Run("This is a demonstration of ");
Bold myBold = new Bold(new Run("RichTextBox "));
Run myRun1 = new Run(" in WPF.");
Paragraph paragraph = new Paragraph();
// Create a paragraph and add the Run and Bold to it.
paragraph.Inlines.Add(myRun);
paragraph.Inlines.Add(myBold);
paragraph.Inlines.Add(myRun1);
// Add the paragraph to the FlowDocument.
myFlowDoc.Blocks.Add(paragraph);
richTextBox.Document = myFlowDoc;
//richTextBox.Document.Blocks.Add(new Paragraph(new Run("This is a demonstration of RichTextBox in WPF.")));
//richTextBox.Selection.SelectionColor = Colo;
//richTextBox.Selection.Changed += Selection_Changed; = FontWeights.Normal;
//richTextBox.Selection.FontStyle = FontStyle.Normal;
//richTextBox.Selection.TextDecorations = null;
}
void Selection_Changed(object sender, RoutedEventArgs e)
{
TextSelection selection = richTextBox.Selection;
if (!selection.IsEmpty)
{
selection.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);
}
}
private void richTextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
TextSelection selection = richTextBox.Selection;
if (!selection.IsEmpty)
{
selection.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);
}
}
private void Bold_Click(object sender, RoutedEventArgs e)
{
TextSelection selection = richTextBox.Selection;
if (!selection.IsEmpty)
{
selection.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
}
}
private void Underline_Click(object sender, RoutedEventArgs e)
{
TextSelection selection = richTextBox.Selection;
if (!selection.IsEmpty)
{
TextDecorationCollection decorations = selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection;
if (decorations == TextDecorations.Underline)
selection.ApplyPropertyValue(Inline.TextDecorationsProperty, null);
else
selection.ApplyPropertyValue(Inline.TextDecorationsProperty, TextDecorations.Underline);
}
}
private void Italic_Click(object sender, RoutedEventArgs e)
{
TextSelection selection = richTextBox.Selection;
if (!selection.IsEmpty)
{
selection.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Italic);
//selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);
}
}
private void Save_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Text File|*.txt|RTF File|*.rtf";
if (saveFileDialog.ShowDialog() == true)
{
using (FileStream fs = File.Create(saveFileDialog.FileName))
{
TextRange range = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
if (saveFileDialog.FilterIndex == 1)
range.Save(fs, DataFormats.Text);
else
range.Save(fs, DataFormats.Rtf);
}
}
}
private void Load_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Text File|*.txt|RTF File|*.rtf|HTML File|*.html|Bitmap Image|*.jpg";
if (openFileDialog.ShowDialog() == true)
{
using (FileStream fs = (FileStream)openFileDialog.OpenFile())
{
//richTextBox.Document.Blocks.Clear();
TextRange range = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
switch (openFileDialog.FilterIndex)
{
case 2:
range.Load(fs, DataFormats.Rtf);
break;
case 4:
//range.Load(fs, DataFormats.Bitmap);
Image image = new Image();
image.Source = new BitmapImage(new Uri(openFileDialog.FileName, UriKind.RelativeOrAbsolute));
image.Width = 200;
InlineUIContainer container = new InlineUIContainer(image);
Paragraph paragraph = new Paragraph(container);
richTextBox.Document.Blocks.Add(paragraph);
break;
default:
range.Load(fs, DataFormats.Text);
break;
}
}
}
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
if (comboBox.SelectedItem != null)
{
ComboBoxItem comboBoxItem = comboBox.SelectedItem as ComboBoxItem;
string strcolor = comboBoxItem.Content.ToString();
TextSelection selection = richTextBox.Selection;
if (!selection.IsEmpty)
{
switch (strcolor)
{
case "Red":
selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);
break;
case "Blue":
selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Blue);
break;
case "Yellow":
selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Yellow);
break;
default:
selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Black);
break;
}
}
}
}
}
}
Features Recap
- Load and save Rich Text files
- Apply text formatting (bold, italic, underline)
- Change font size dynamically
Summary
This simple WPF RichTextBox editor shows how easy it is to create a text editing application with formatting capabilities. By leveraging built-in WPF controls and applying formatting to selected text, you can extend it into a full-featured desktop word processor. I hope this was helpful to you
Thanks