views:

304

answers:

1

Our tester threw curly brackets at our persisting WPF RichTextBoxes. On save and reopen, there are magically more curly brackets.

I've condensed the issue / code down.

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>

 <RichTextBox x:Name="rtb1" />
 <Button Grid.Row="1" Click="Button_Click">Draw a fish</Button>
 <RichTextBox x:Name="rtb2" Grid.Row="2"/>
</Grid>
</Window>

Two rich text boxes. On button click, the bottom one gets set to the result of the first one after persist and restore.

namespace WpfApplication1
{
 /// <summary>
 /// Interaction logic for Window1.xaml
 /// </summary>
 public partial class Window1 : Window
 {
  public Window1()
  {
   InitializeComponent();

   rtb1.Document = new FlowDocument(new Paragraph(new Run("{")));
  }


  public static FlowDocument CreateFlowDocumentFromByteArray(byte[] byteArray)
  {
   return (FlowDocument)XamlReader.Load(new MemoryStream(byteArray));
  }

  public static byte[] CreateByteArrayFromFlowDocument(FlowDocument flowDocument)
  {
   MemoryStream mStream = new MemoryStream();
   XmlWriterSettings settings = new XmlWriterSettings();
   settings.Indent = false;
   settings.OmitXmlDeclaration = true;
   XamlDesignerSerializationManager dsm = new XamlDesignerSerializationManager(XmlWriter.Create(mStream, settings));
   dsm.XamlWriterMode = XamlWriterMode.Value;
   XamlWriter.Save(flowDocument, dsm);
   mStream.Close();
   return mStream.ToArray();
  }

  private void Button_Click(object sender, RoutedEventArgs e)
  {
   rtb2.Document = CreateFlowDocumentFromByteArray(CreateByteArrayFromFlowDocument(rtb1.Document));
  }

 }
}

Why is this happening? How do we stop it?

+1  A: 

I'll test the code more thoroughly tonight, but does it happen when the braces are not at the start of the text? E.g., if your run was "Hello{World}" does it still do this?

As you probably know, curly braces are significant in WPF because they are used for markup extensions. The following markup wouldn't work:

<Button Content="{Hello}" />

To get the right output, you'd usually escape it with:

<Button Content="{}{Hello}" />

Since you're using XamlReader.Load, there may be some confusion around the use of {}'s in the XAML, so they are being escaped. But that's just a guess. Out of interest, what does the XAML which is written out look like?

Paul Stovell
It does only do it when it's at the start. When you write it out, it does have {}{
Donnelle
To be more precise, this occurs only when the curly brackets are at the start of a paragraph. We have a workaround (since we were already walking the tree applying styles) but it's just more overhead, and we are pretty frustrated that this happened at all.
Donnelle