Search code examples
wpfflowdocumentxamlreaderflowdocumentreader

How can I keep XamlReader.Load(xamlFile) from inserting extra Run elements?


Imagine I've got a FlowDocument like so:

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              ColumnWidth="400" FontSize="14" FontFamily="Georgia"
              Name="document">
    <Paragraph KeepTogether="True">
        <Run>ABC</Run>
        <Run>DEF</Run>
        <Run>GHI</Run>
    </Paragraph>
</FlowDocument>

And I load it like so:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        FileStream xamlFile = new FileStream("FlowDocument1.xaml", FileMode.Open);
        FlowDocument content = XamlReader.Load(xamlFile) as FlowDocument;
        fdReader.Document = content;
    }

What results is this:

enter image description here

While what I'd like to see is something like so:

enter image description here

but upon examining the FlowDocument in the watch window, I see that it inserts Runs between them that essentially have a space as their content, so rather than there being the 3 Inlines that I expect inside the Paragraph, there are 5.

How can I avoid those blank runs being inserted?

Note: I can't really group those three runs into a single one, which would be the easy answer, due to the fact that they need to remain separate objects.

Ideas?


Solution: As Aaron correctly answered below, grouping the Runs all on one line fixes this issue. As an aside, this document was being built on the fly from other data (more complex than my example) and written out using an XmlWriter that had the XmlWriterSettings property Indent set to true (because it was easier to see the output rather than it all running together) - setting it to false eliminates those extra Runs when it is read in by the XamlReader.


Solution

  • You can simply place all your runs on a single line...

    <FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  ColumnWidth="400" FontSize="14" FontFamily="Georgia"
                  Name="document">
        <Paragraph KeepTogether="True">
            <Run>ABC</Run><Run>DEF</Run><Run>GHI</Run>
        </Paragraph>
    </FlowDocument>
    

    You can then access each run via the InlineCollection...

    foreach (var run in ((Paragraph)content.Blocks.FirstBlock).Inlines)
    {
       //do stuff with run             
    }