DataBinding tabular data to a FlowDocument

Technorati Tags:

I’ve come back to WPF development after an initial look at it.

One of the tasks I had was to provide a viewer for text event messages. There were a number of requirements over a basic viewer…

•    It needed to support ‘rich text’; like bold, italic and coloured text.
•    It needed to support Copy and Paste into Word.
•    Print (with preview) was required.
•    and it had to be searchable.

I looked initially at the RichTextBox control and while this did a lot of what I wanted it seemed as if the FlowDocument control did just about everything. The big problem I had was the lack of data binding. I solved part of that when I can across the BindableRun code here that allowed me to bind text to a Run element in a FlowDocument. The next problem was how to bind to a table of messages.

FlowDocuments can contain tabular data but as with the Run there was no way to databind. Until, that is, I found Vincent Van Den Berghe’s article in MSDN Mag (April, 2009, page 59). The article explains how he did it.

There was one piece of functionality that didn’t work. My test application worked fine if I populated the table before the document was rendered, but failed to detect changes and update itself. Specifically, I added some code that went off to the Google Translation Service to translate my messages into another language and the translated messages weren’t being rendered. I finally solved this by adding in a handler for the CollectionChanged event.

[One thing I find frustrating with WPF samples is the [over]use of static resources for data. In the real world your data will be coming from some source; DB, Object Class. Static resources often mask other issues; like not handling a change in a collection…rant over]

So, why not simply embed a UI table; like a ListBox or GridView into the FlowDocument? The answer is simple; you can’t search the data in embedded controls and if you copy the FlowDocument contents into Word, the UI elements don’t come across. This even applies to simple elements; like TextBlock.

Here’s the source code which also includes a Print Preview control.

You should be able to get the sample code here.


Tags: , ,

5 Responses to “DataBinding tabular data to a FlowDocument”

  1. Musaab Says:

    Hi , nice article , everything went well and I could bind my table to an ObservableCollection , but I’m having a weird problem, the table appear normally but it disappear in the printed version of the FlowDocument, the ItemsContent is there , I know that because I’ve changed its Background , it appears on the printed version but it seems the the table loses the binding on print , any suggestions ?

    thanks in advance

    • robertgtaylor1 Says:

      I added print/print preview to my work and it worked, but you have problems with UI elements; like Buttons as these don’t get printed. I recall that I found some other blogs about this. In my case the text was a list of messages and someone tried to add a bit of eye-candy by putting a nice border round each message. Looked great but the page came out blank when printed.

      Glad you found the article/code useful.

  2. Musaab Says:

    Thanks for the reply , I solved the problem , find the full story on StackOverFlow

    it seems that when printing the flowdocument is put into a special print context and loses the datacontext of the window

  3. Mark Welch Says:

    How can we use this code sample? Can you specify the license that you intended for this code? (I can’t use the code until I know that the license allows it, and I’d like to if possible.)

    Thanks for posting this article.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: