I'm currently trying to get a RichTextBox with basic formatting working for my new beta note software, Lilly Notes . Brian Lagunas' article on this subject set me in the right direction, but I have a problem. If you click the underlined text, the underline button will be pressed, so the status will be recognized. However, if I serialize it to RTF and then deserialize it back to RichTextBox, it is not detected. Since the code in Lilly Notes is not trivial to demonstrate here, I created SSCCE to demonstrate the problem.
Firstly, MainWindow.xaml:
<Window x:Class="WpfRichTextBoxUnderline.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <DockPanel LastChildFill="True"> <Button Name="SaveAndReloadButton" Content="Save and Reload" DockPanel.Dock="Bottom" Click="SaveAndReloadButton_Click" /> <ToggleButton Name="UnderlineButton" DockPanel.Dock="Top" Width="20" Command="{x:Static EditingCommands.ToggleUnderline}" CommandTarget="{Binding ElementName=RichText}"> <ToggleButton.Content> <TextBlock Text="U" TextDecorations="Underline" /> </ToggleButton.Content> </ToggleButton> <RichTextBox Name="RichText" SelectionChanged="RichTextBox_SelectionChanged" /> </DockPanel> </Window>
It looks like this:

In the code code, I have code to determine the formatting state when changing the selection and accordingly updating the state of the underline button. This is no different from the Brian Lagunas method.
private void RichTextBox_SelectionChanged(object sender, RoutedEventArgs e) { if (this.RichText.Selection != null) { object currentValue = this.RichText.Selection.GetPropertyValue(Inline.TextDecorationsProperty); this.UnderlineButton.IsChecked = (currentValue == DependencyProperty.UnsetValue) ? false : currentValue != null && currentValue.Equals(TextDecorations.Underline); } }
Then I have a method (and another helper method) that saves the RTF to a string and then applies it to the RichTextBox. Again, I do it simply to make it simple - in Lilly Notes I save this line in the database and then load it back when the application starts again.
public Stream GenerateStreamFromString(string s) { MemoryStream stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); writer.Write(s); writer.Flush(); stream.Position = 0; return stream; } private async void SaveAndReloadButton_Click(object sender, RoutedEventArgs e) { string data = null; var range = new TextRange(this.RichText.Document.ContentStart, this.RichText.Document.ContentEnd); using (var memoryStream = new MemoryStream()) { range.Save(memoryStream, DataFormats.Rtf); memoryStream.Position = 0; using (StreamReader reader = new StreamReader(memoryStream)) { data = await reader.ReadToEndAsync(); } }
After I click the Save and Reload button and the RTF is serialized into a string and deserialized back to the RichTextBox, the underline definition no longer works, and when I click the underlined text, the button remains as if the underline does not work:

Now that I was debugging this, I noticed this:

Initially, when you click on a piece of underlined text, you get a TextDecorationCollection with a Count of 1. But after saving and reloading, you get a Count from zero, so the detection does not work.
Note that this issue only applies to underline / strikethrough, which are related to TextDecorationCollection in WPF. Bold and italics do not show this problem.
Is this happening because I'm doing something wrong, or is it a bug with the RichTextBox?
In my BitBucket registry, you can find the SSCCE code here .