tags:

views:

571

answers:

7

Greetings, I have a problem with printing in WPF. I am creating a flow document and add some controls to that flow document. Print Preview works ok and i have no problem with printing from a print preview window. The problem exists when I print directly to the printer without a print preview. But what is more surprisingly - when I use XPS Document Writer as a printer everyting is ok, when i use some physical printer, some controls on my flow document are not displayed. Thanks in advance

A: 

Maybe the physical printer you are using has some compatibility issues, have you tried printing the XPS Document that you create when you print to the XPS Writer?

luvieere
+1  A: 

XPS Document can be printed without a problem

Peter
A: 

Try using this code. It wraps the FlowDocument in a FixedDocument prior to printing, to prevent layout changes and allow for margins and header.

luvieere
well, I am already using this technique
Peter
A: 

well, any others suggesstions for this issue?

Peter
A: 

i have noticed one thing: tip: the controls that are not displayed are the controls I am binding some data, so the conclusion is that the binding doesn't work. Can it be the case that binding is not executing before sending the document to the printer?

Peter
Peter, a usage tip for Stackoverflow - if you want to add information you should edit your original question, not post "answers". In general if you want to respond to a particular answer use a comment (hmm, except that you may not be able to yet!)
Murph
ok , from now i will do so, thanks for the tip
Peter
A: 

Did you get this resolved? I'm having the same problem. It would appear that the document is rendered on the UI thread after printing is kicked off. At least, that's my guess.

Ross
A: 

Important thing to note : You can use XpsDocumentWriter even when printing directly to a physical printer. Don't make the mistake I did of avoiding it just because you're not creating an .xps file!

Anyway - I had this same problem, and none of the DoEvents() hacks seemed to work. I also wasn't particularly happy about having to use them in the first place. In my situation some of the databound controls printed fine, but some others (nested UserControls) didnt. It was as if only one 'level' was being databound and the rest wouldn't bind even with a 'DoEvents()' hack.

The solution was simple though. Use XpsDocumentWriter like this. it will open a dialog where you can choose whichever installed physical printer you want.

        // 8.5 x 11 paper
        Size sz = new Size(96 * 8.5, 96 * 11);

        // create your visual (this is a WPF UserControl)
        var template = new PackingSlipTemplate()
        {
            DataContext = new PackingSlipViewModel(order)
        };

        // arrange
        template.Measure(sz);
        template.Arrange(new Rect(sz));
        template.UpdateLayout();

        // print to XpsDocumentWriter
        // this will open a dialog and you can print to any installed printer
        // not just a 'virtual' .xps file
        PrintDocumentImageableArea area = null;
        XpsDocumentWriter xps = PrintQueue.CreateXpsDocumentWriter(ref area,);

        xps.Write(template);

I found the OReilly book on 'Programming WPF' quite useful with its chapter on Printing - found through Google Books.


If you don't want a print dialog to appear, but want to print directly to the default printer you can do the following. (For me the application is to print packing slips in a warehouse environment - and I don't want a dialog popping up every time).

        var template = new PackingSlipTemplate()
        {
            DataContext = new PackingSlipViewModel(orders.Single())
        };

        // arrange
        template.Measure(sz);
        template.Arrange(new Rect(sz));
        template.UpdateLayout();

        LocalPrintServer localPrintServer = new LocalPrintServer();
        var defaultPrintQueue = localPrintServer.DefaultPrintQueue;

        XpsDocumentWriter xps = PrintQueue.CreateXpsDocumentWriter(defaultPrintQueue);
        xps.Write(template, defaultPrinter.DefaultPrintTicket);
Simon_Weaver