In my MVVM WPF application I’m using a databound flowdocument. I used the technique described here to be able bind my data to the flowdocument.
My flowdocument is bound to a public property in my viewmodel. The property is an ienumerable of a custom type, like this:
public IEnumerable<Person> Persons
{
get { return _persons; }
set { _persons = value; }
}
The flowdocument is shown in a FlowDocumentScrollViewer control. The document looks like:
code name lastname
---- ----- ---------
1 john johnson
1 peter peterson
2 jane jane
3 john doe
The binding works fine however I want to add a blank line after each distinct code:
code name lastname
---- ----- ---------
1 john johnson
1 peter peterson
2 jane jane
3 john doe
My Xaml in the view is:
<FlowDocumentScrollViewer>
<FlowDocument>
<flowdoc:ItemsContent ItemsSource="{Binding Path=Persons}">
<flowdoc:ItemsContent.ItemsPanel>
<DataTemplate>
<flowdoc:Fragment>
<Table BorderThickness="1" BorderBrush="Black">
<TableRowGroup flowdoc:Attached.IsItemsHost="True">
<TableRow Background="LightBlue">
<TableCell>
<Paragraph>ronde</Paragraph>
</TableCell>
<TableCell>
<Paragraph>hal</Paragraph>
</TableCell>
<TableCell>
<Paragraph>datum</Paragraph>
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</flowdoc:Fragment>
</DataTemplate>
</flowdoc:ItemsContent.ItemsPanel>
<flowdoc:ItemsContent.ItemTemplate>
<DataTemplate>
<flowdoc:Fragment>
<TableRow>
<TableCell>
<Paragraph>
<flowdoc:BindableRun BoundText="{Binding Path=Code}" />
</Paragraph>
</TableCell>
<TableCell>
<Paragraph>
<flowdoc:BindableRun BoundText="{Binding Path=Name}" />
</Paragraph>
</TableCell>
<TableCell>
<Paragraph>
<flowdoc:BindableRun BoundText="{Binding Path=LastName}" />
</Paragraph>
</TableCell>
</TableRow>
</flowdoc:Fragment>
</DataTemplate>
</flowdoc:ItemsContent.ItemTemplate>
</flowdoc:ItemsContent>
Any suggestions on how to do this without breaking the MVVM rules? It seems like databinding a flowdocument comes with the price of inflexible layout.
Thanks in advance
In order to group your data, use a
CollectionViewSourcelike this:The
CollectionViewSourceelement above sorts thePersonslist by code and determines the groups.Furthermore, you must adapt the
ItemsContentclass, because the one from the MSDN article does not yet support grouping. Here is a very simple example how you could achieve that:Most of the code above is from the original MSDN article; the only changes I made are these:
foreachloop to the new methodGenerateContentForUngroupedItems.if (panel==null)“) outside the loop.NEW CODE.What the modified code does is this: if the items source is not a collection view, it works exactly like the original MSDN code. If the items source is a collection view, two nested loops are called:
The inner loop effectively is the same as the original foreach loop from the MSDN article.
In the added code above, the empty table row is added by these lines:
This code, of course, is not very generic. For a generic solution, add a new dependency property to the
ItemsContentcontrol which contains a data template, just like theItemsPanelorItemTemplateproperties. Then, you have the possibility to insert arbitrary text at the end of the group.The result looks like this: