WPF Printing Part 2 – The Fixed Document

This is part 2 of a series about printing in WPF, in the previous part we printed the content of a WPF visual, in this part we’ll create and print a fixed document, in the end of the previous post I wrote well deal with choosing printers and setting up print settings – but actually printing is more interested and I’ll get to printer management later in this series.

Printing a FixedDocument is the simplest way to do some “real” printing with control over paging, margin and everything else.

The code is much longer than the examples in the previous post but it’s not complicated, take the program from the previous post and replace the content of Print_Click with the following code.

First we have to get the printer settings, we especially need the page size in order to create a document with the same page size, we’ll just use PrintDialog like we did before:

// select printer and get printer settings
PrintDialog pd = new PrintDialog();
if (pd.ShowDialog() != true) return;

Now create a document and set it’s page size:

// create a document
FixedDocument document = new FixedDocument();
document.DocumentPaginator.PageSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);

Create a page and again set the page size:

// create a page
FixedPage page1 = new FixedPage();
page1.Width = document.DocumentPaginator.PageSize.Width;
page1.Height = document.DocumentPaginator.PageSize.Height;

Create a TextBlock and add it to the page:

// add some text to the page
TextBlock page1Text = new TextBlock();
page1Text.Text = "This is the first page";
page1Text.FontSize = 40; // 30pt text
page1Text.Margin = new Thickness(96); // 1 inch margin
page1.Children.Add(page1Text);

And add the page to the document, this is a little tricky because we need to use a PageContent object as an intermediary and it looks like there is no way to add the page to the page content, the trick is to use the IAddChild interface – according to the documentation you’re not supposed to use IAddChild directly but it’s the only way to build a fixed document.

// add the page to the document
PageContent page1Content = new PageContent();
((IAddChild)page1Content).AddChild(page1);
document.Pages.Add(page1Content);

Now repeat all the steps for the second page:

// do the same for the second page
FixedPage page2 = new FixedPage();
page2.Width = document.DocumentPaginator.PageSize.Width;
page2.Height = document.DocumentPaginator.PageSize.Height;
TextBlock page2Text = new TextBlock();
page2Text.Text = "This is NOT the first page";
page2Text.FontSize = 40;
page2Text.Margin = new Thickness(96);
page2.Children.Add(page2Text);
PageContent page2Content = new PageContent();
((IAddChild)page2Content).AddChild(page2);
document.Pages.Add(page2Content);

And print the resulting document:

// and print
pd.PrintDocument(document.DocumentPaginator, "My first document");

The result of all this work is this very impressive document:

[Document Image]

At point we are wasting a lot of paper and a print preview feature starts to look real nice, on the next post we’ll talk briefly about all the “magic numbers” in this sample code and in the post after that we’ll jump right into building a print preview window.

posted @ Monday, April 20, 2009 12:56 PM

Comments on this entry:

# re: WPF Printing Part 2 – The Fixed Document

Left by Genny at 5/13/2009 7:57 AM

Hi ,
i read your topic and it's useful for me cos i'm studing about Print with WPF so i will ask you a question: I need create some report that contain PageHeader,PageFooter and PageNumber to print in MultiPage can you advice me witch is the right way to create my own routine to work out that?
Have a Good Job

# re: WPF Printing Part 2 – The Fixed Document

Left by Raju David at 12/4/2009 5:14 AM

Hi,

Thanks for the information.

my requirement is like this,

I have one DataGrid and print button.DataGrid have columns with Imagename and imagepath.When i click on Print button,I want to print Image name with first page of the image from loading image.
am beginer in WPF. how can do this by using WPF?

thanks in advance

# re: WPF Printing Part 2 – The Fixed Document

Left by Syed at 8/4/2010 6:14 PM

hi,can u provide me some useful information regarding printing image in the WPF.
thanks in advance..

# re: WPF Printing Part 2 – The Fixed Document

Left by Anas at 5/23/2011 12:05 PM

Hi any body tell me what is the problem when i reduce the font size to 14 it don't print the data
thanks

# re: WPF Printing Part 2 – The Fixed Document

Left by setiri at 6/13/2011 2:46 AM

it looks like you can assign the fixedpage to the pagecontent by useing pagecontent.child = fixedpage;

seems to work for me.

# re: WPF Printing Part 2 – The Fixed Document

Left by Will at 7/18/2012 5:41 PM

Best multiple page printing example I have found.

Great job.

# re: WPF Printing Part 2 – The Fixed Document

Left by jaison at 10/11/2012 6:23 AM

thank you so much sir...god bless u

# re: WPF Printing Part 2 – The Fixed Document

Left by Siva at 12/26/2012 11:34 AM

if i add more than 500 pages in The Fixed Document throws error , insufficient memory to continue , how to resolve this one

# re: WPF Printing Part 2 – The Fixed Document

Left by varun at 7/30/2013 1:55 PM

This is the best example which i got after so much of research from google.

Thank you so much

# re: WPF Printing Part 2 – The Fixed Document

Left by Kian Mayne at 12/1/2013 6:45 PM

Can't you just set the page content like this:
FixedPage fp = new FixedPage();
PageContent pContent = new PageContent();
pContent.Child = fp;

# re: WPF Printing Part 2 – The Fixed Document

Left by Kevin at 11/19/2014 2:35 AM

This is an awesome example.

Ported to VB. Paste into MainWindow.xaml.vb.

Imports System.Windows.Markup

Class MainWindow

Private Sub Print_Click(sender As Object, e As RoutedEventArgs)
Dim pd As New PrintDialog
If pd.ShowDialog = False Then Return

' // create a document
Dim document = New FixedDocument
document.DocumentPaginator.PageSize = New Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight)

' // create a page
Dim Page1 As New FixedPage
Page1.Width = document.DocumentPaginator.PageSize.Width
Page1.Height = document.DocumentPaginator.PageSize.Height


' // add some text to the page
Dim page1text As New TextBlock
With page1text
.Text = "This is the 1st page."
.FontSize = 40
.Margin = New Thickness(96)
End With
Page1.Children.Add(page1text)

' // add the page to the document

Dim Page1Content As New PageContent
DirectCast(Page1Content, IAddChild).AddChild(Page1)
document.Pages.Add(Page1Content)


' // do the same for the second page

Dim Page2 As New FixedPage
Page2.Width = document.DocumentPaginator.PageSize.Width
Page2.Height = document.DocumentPaginator.PageSize.Height

Dim page2text As New TextBlock
With page2text
.Text = "This is the 2nd page."
.FontSize = 40
.Margin = New Thickness(96)
End With
Page2.Children.Add(page2text)

' // add the page to the document

Dim Page2Content As New PageContent
DirectCast(Page2Content, IAddChild).AddChild(Page2)
document.Pages.Add(Page2Content)

' // and print
pd.PrintDocument(document.DocumentPaginator, "My first document")

End Sub
End Class

# re: WPF Printing Part 2 – The Fixed Document

Left by Gregory at 2/20/2015 10:21 PM

The code in this example seems to work, but I am having an issue when trying to send the controls that I already placed on my xaml window to the fixedpage object. I am getting an exception that says that the control already has a logical parent and that it should be disconnected first. What should I do here? Anyone?
Please, help!

# re: WPF Printing Part 2 – The Fixed Document

Left by Akira Chen at 2/26/2016 10:00 AM

How can I print a grid that exceeds one page? I have a grid created programmatically and I want to use FixedDocument/FixedPage to print the grid with margin. How do I achieve this goal?

# re: WPF Printing Part 2 – The Fixed Document

Left by Akira Chen at 2/26/2016 1:56 PM

Hello, Dennis! I have a question about multipage FixedPage.
I have a Grid created programmatically and the Grid exceeds one A4 page.
Now I want to print the Grid in several FixedPage with print margin.
But on my way, I create the Grid repeatedly and offset the LeftTop point in the fixedPage Arrange function.
I meet a problem that I cannot set print margin in fixedPage, because I set the print margin to the fixedPage and then the first page will have print margin and the next pages will be blank.

PrintDialog pd = new System.Windows.Controls.PrintDialog();
if (pd.ShowDialog() == false)
{
return;
}

var pageSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);
var document = new FixedDocument();
document.DocumentPaginator.PageSize = pageSize;

for (int nPage = 0; nPage < MaxPage; nPage++)
{
Grid tempGrid = LoadControlMotherInit();

tempGrid.Width = GridWidth;
tempGrid.Height = GridActualHeight;

Point leftTop = new Point();

leftTop.X = 10;
leftTop.Y = -nPage * pageSize.Height;

// Create FixedPage
var fixedPage = new FixedPage();
fixedPage.Width = pageSize.Width;
fixedPage.Height = pageSize.Height;

fixedPage.Margin = new Thickness(0, 0, 0, 96);

fixedPage.Children.Add((UIElement)tempGrid);
fixedPage.Measure(pageSize);
fixedPage.Arrange(new Rect(leftTop, pageSize));

fixedPage.UpdateLayout();

// Add page to document
var pageContent = new PageContent();
((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
document.Pages.Add(pageContent);
}

pd.PrintDocument(document.DocumentPaginator, "My Document");

# re: WPF Printing Part 2 – The Fixed Document

Left by Akira Chen at 3/1/2016 3:18 AM

How do I print a GroupBox that contain multipage content?
How do I set the print margin on every page?

Your comment:



 (will not be displayed)


 
 
Please add 1 and 8 and type the answer here: