views:

503

answers:

2

I have a WPF window with a frame. I have some code to print out the content of the frame using the printdialog and printvisual. But this will only print what appears on the screen even though the frame scrolls and other parts are available.

Is there a way to add pagination and make sure that the entire content of my frame will print.

Or is there another way to take my frame content and print it? i.e. to not use printvisual?

A: 

You can loop recursively through the visual tree with the VisualTreeHelper and translate all found controls to a Elements for use in a flow-document. This flow-document you can print. I think there is no acceptable way to print a contents directly from gui.

martin
+7  A: 

Yes. I've done this. It is not very difficult.

  1. Wrap your Frame inside a ScrollViewer which normally has its horizontal and vertical scrolling disabled

  2. When you're ready to print, enable vertical scrolling. This will cause the Frame to be told it has infinite vertical space, so it will render all of the content. Then call UpdateLayout() to get the layout to update.

  3. Implement IDocumentPaginator to return the same Frame for each page but adjust the clip and RenderTransform each time to show a different portion of the actual Frame.

  4. Print using your custom IDocumentPaginator

The above description assumes that you want to fix the width of the frame to the page width and paginate it vertically. This would be appropriate for a web page but not for a spreadsheet. For spreadsheet-like content you would set the ScrollViewer to allow scrolling in both directions, giving the frame infinite space each way. In this case the IDocumentPaginator is the same except the RenderTransforms and clipping are chosen to iterate both horizontally and vertically.

This technique actually works for any WPF content, not just a Frame.

Ray Burns