VisualTargetDemo code and printing problem

Oct 20, 2010 at 4:14 PM

Hi, Dwayne.

In my reporting application I have to print a canvas in multipaged mode (if the canvas is large and doesn`t fit the one page of selected size). So, for every page I must create new copy of canvas via serialization/deserialization (each time I creating a FixedPage and adding it it FixedDocument) which can affect application`s performance and freeze the GUI significantly if pages count appears to be greater than, lets say, 5.

I`ve found your demo and liked it very much. It is almost all I needed to solve this problem. So I moved your VisualTargetDemo related sources to my project, adapted a little and launched the application. And for some reason canvas stays invisible on fixed page. I tried a lot to understand why this happens and fix this, but with no success: canvas exists (I mean VisualWrapper->HostVisual->My canvas tree), all is measured/arranged correctly, but canvas is totally invisible. The grid on FixedPage where the VisualWrapper is placed is rendered correctly.

Maybe you can help me with this? All code is nearly the same as yours (I`ll give you some key parts if needed, anyway), except that I am adding the VisualWrapper with all needed stuff on a fixed page and print the fixed document, instead of rendering it on window, user control or some other GUI element.

PS I tried the same while rendering canvas in GUI - all works fine. Seems that there should be some tricky part when rendering it to FixedPage or I just missed something...

Thanks in advance.

Oct 20, 2010 at 5:29 PM

Do I understand correctly that you are printing (from the UI thread) an element tree that contains a VisualWrapper->HostVisual->Canvas (where the canvas is on another thread)?

If so, I suspect the problem is that the printing code doesn't know what to send the printer when it gets to the HostVisual.  The printing path just calls GetDrawing to get the render data for this element and continues recursing into any children.  HostVisual has no children, and I'm sure GetDrawing is empty too.

You could try overriding GetDrawing on your HostVisual and marshalling the call over to the worker thread to get the drawing over there, freeze it, and return it back to the UI thread.  Of course, computing the composed drawing for an entire subtree is complicated and is effectively what the print path is doing.  So you would be reinventing alot of code.  Ifeanyi has some example code for how to do this over on his codeplex site:  You could always cheat and just call RenderTargetBitmap.

Another option would be to move more stuff to your worker thread.  You only need the HostVisual if you want to incorporate the display of the visual into your UI tree.  You can always create elements on whichever thread you like, but they won't get shown on the screen unless they are in their own HWND or spliced into another thread's HWND via HostVisual.  Anyways, you could serialize everything you want to print over to the other thread, deserialize it, and print it.

Good luck