Question

So I have been building a WPF application that prints over some forms. These forms come preprinted with only blank spaces where you are supposed to write in some information. WPF app needs to precisely print text so that text printed by WPF aligns perfectly with text and blanks in preprinted form. And by using DocumentViewer and FixedDocument I was able to largely succed at the task.

The big bugbear was that for some reason VS WPF designer doesn't like when you put PageContent into FixedDocument in DocumentViewer even though you can put PageContent in any other container (like Scroll Viewer) and it would get rendered perfectly. But even if VS XAML parser was being incoperative I could compile and run my app with no problems.

Problems on the other came from my inability to find a way to hide some elements in FixedDocument from printing. In order for the user to enter information into the app more preciselly and to know where in the printed form I would place that info, I put the scanned image of the form in the background of the FixedDocument. But I only want it to be displayed when the user is viewing the document in the DocumentViewer, I don't want that image to be printed when he presses print button.

Now in Windows forms I could handle OnPrint event and using IsPrintPreview property I could decide what to print and what not to. DocumentViewer on the other hand seemingly doesn't allow me to decide what to print and what not to print.

Soooo, long story short, is there a way to hide certain controls in a FixedDocument from printing in DocumentViewer?

Was it helpful?

Solution

I "solved" the problem. Well for certan definition of solved. For future reference what I did was override DocumentViewer's own print code by attaching my own on Print command:

<DocumentViewer.CommandBindings>
   <CommandBinding Command="ApplicationCommands.Print" Executed="PrintExecute"/>
</DocumentViewer.CommandBindings>

And than in my code I would hide things in the document that I don't want printed, show the dialog and than using XPSDocumentWriter "print" the document into printing quee. Important thing here is to do the printing in Sync and not Async becuase you can only re display things that you have hidden AFTER you have sent the document into printing. Anyway this code is based on this workaround for landscaping pages in WPF.

Anyway the code, it hides all images (makes them transparent), then does the printing and only after printing redisplays them.

DocumentViewer dv = sender as DocumentViewer;
FixedDocument dokument = dv.Document as FixedDocument;
if (dokument == null) return;
PageContent content = dokument.Pages.First();
foreach (UIElement el in content.Child.Children)
{
     Image image = el as Image;
     if (image != null)
         image.Opacity = 0;
}
PrintDialog dialog = new PrintDialog();
dialog.PrintQueue = LocalPrintServer.GetDefaultPrintQueue();
dialog.PrintTicket = dialog.PrintQueue.DefaultPrintTicket;
dialog.PrintTicket.PageOrientation = PageOrientation.Landscape;

if (dialog.ShowDialog() == true)
{
    XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(dialog.PrintQueue);
    writer.Write(dokument, dialog.PrintTicket);
}
foreach (UIElement el in content.Child.Children)
{
    Image image= el as Image;
    if (image!= null)
        image.Opacity = 0.75;
}

Of course there is still at least one problem. For the user the background WILL dissapear while the dialog is open, and I don't see me solving that problem simply since Document Viewer doesn't differentiate between what user sees and what gets sent to the computer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top