I have some data that I want to present in a FlowDocument
. This will basically be a view that explains the data in a friendly way, with section headers, paragraphs of text, etc., and which I will display in a FlowDocumentScrollViewer.
To this end, I would like to create a bulleted list (<List>
) out of the contents of an ObservableCollection
. I know how to do that with ItemsControl
, but how do I do it for ListItem
elements in a FlowDocument
, since they're part of the TextElement
class hierarchy rather than the Control
hierarchy? Is there an equivalent of ItemsControl
for text content inside a TextBlock
or FlowDocument
?
Edit: The article Sergey linked to is the perfect starting point. The only problem is that the article's code can only use a Section
or a TableRowGroup
as the items panel, and doesn't yet support using a <List>
. But that was trivial to fix -- just a matter of adding this code at the end of ItemsContent.GenerateContent
, just before the final else
:
else if (panel is List)
((List) panel).ListItems.Add((ListItem) element);
What you are looking for is possible, but requires significant amount of coding. Fortunately, Vincent Van Den Berghe posted a nice article on the MSDN describing how to Create Flexible UIs With Flow Documents And Data Binding , including the code!
Instead of using a
FlowDocument
, you can use anItemsControl
and change the panel used to display items to a WrapPanel. This will allow you use theItemsControl
as you want, but change its display semantics to aWrapPanel
(which I believe functions like aFlowDocument
. You'd do it something like this:You can set any properties on the inner
WrapPanel
as you desire.I think you are looking for the List element: http://msdn.microsoft.com/en-us/library/system.windows.documents.list.aspx
Bubblewrap points out a few more details. You'd likely bind to the ListItems property and need to use a ValueConverter to convert your source list to a list of type ListItemsCollection.
Bubblewrap points out that this is readonly and that the ListItemsCollection has an internal constructor. So...
I think what you'd have to do is this:
This is pretty unfortunate, but I think it would work. You'd have to write a converter to create a new List object and call
.Add(
on each item.