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

737 views Asked by At

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.

2

There are 2 answers

1
Aaron McIver On BEST ANSWER

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             
}
0
Glenn Slayden On

Upvoted the question; who would have guessed that the XAML:

<TextBlock.Inlines><Run Text="[" /><Run Text="0" /><Run Text="-" /><Run Text="2" /><Run Text="]" /></TextBlock.Inlines>

would give different result from:

<TextBlock.Inlines>
    <Run Text="[" />
    <Run Text="0" />
    <Run Text="-" />
    <Run Text="2" />
    <Run Text="]" />
</TextBlock.Inlines>

The first gives "[0-2]" while the second gives "[ 0 - 2 ]". Note, especially, that in the second case, the first and last Run also get special treatment, since there is no space inserted before (or after) those.

Obviously, the convenience feature where the Inline grabs raw XAML for its Run children is not defeated, even when (at least one) Inline is explicitly provided.