Question

Is there any way to print in memory collection or variable size in WPF?

I am using the following code in which I print the ListView control. But when the content is larger than the vertical scroll bar takes over and cuts the content.

 PrintDialog printDialog = new PrintDialog();
                printDialog.ShowDialog();

                printDialog.PrintVisual(lvDocumentSummary, "testing printing!");
Was it helpful?

Solution

To print multiple pages you just need to use a class that implements DocumentPaginator FixedDocument is one of the more complex implementations, FlowDocument is a simpler one.

FlowDocument fd = new FlowDocument();

foreach(object item in items)
{
    fd.Blocks.Add(new Paragraph(new Run(item.ToString())));
}

fd.Print();

or

PrintDialog pd = new PrintDialog();
pd.PrintDocument(fd);

OTHER TIPS

FixedDocument supports DataBinding (other than FlowDocument) like any other xaml document. just host the listview in a fixeddocument and display it in a DocumentViewer (which has built-in print support).

however, if your list is too long for one page, FixedDocument does not automatically generate a new page (like flowdocument does). therefore you have to create a new page maually with code, as this cannot be done in pure xaml.

If you want nice printing from WPF you need to build a FixedDocument and print that, unfortunately it can be very complex depending on what you are trying to print.

There's some example code that creates a FixedDocument here: http://www.ericsink.com/wpf3d/B_Printing.html

Here's a 2019 answer. Some of the old answers don't work anymore, eg. FlowDocumentReader doesn't have a Print method.

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            FlowDocument fd = new FlowDocument();
            foreach (var item in COLLECTION) //<- put your collection here
            {
                fd.Blocks.Add(new Paragraph(new Run(item.ToString())));
            }

            PrintDialog pd = new PrintDialog();
            if (pd.ShowDialog() != true) return;

            fd.PageHeight = pd.PrintableAreaHeight;
            fd.PageWidth = pd.PrintableAreaWidth;

            IDocumentPaginatorSource idocument = fd as IDocumentPaginatorSource;

            pd.PrintDocument(idocument.DocumentPaginator, "Printing Flow Document...");
        }
    }

Interesting, Is the ListView virtualized? If it is, the object are not drawn, that is a possibility. Take a look at the Printing example from Petzold.

Here is my solution to this problem. It is kinda shaky but works for my scenario.

I read my collection and transform it into a string. The whole collection now resides in a StringBuilder object. Next, I saw the text/string into a file on the client's machine and then run the notepad process with /p to print the contents of the file.

It works and it prints the contents successfully.

Finally, there is a timer which is called after 5 seconds and which removes the file. Basically within 5 seconds the request is already sent to the printer queue. But a better solution will be to make sure that the print job has been processed this way you will be 100% sure that the job has been performed.

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