Click here to Skip to main content
Click here to Skip to main content

Silverlight 4 - Converting to image and printing a UIElement in multiple pages

, 2 Sep 2011
Rate this:
Please Sign up or sign in to vote.
Silverlight 4 printing restricts any control to print in a single page, leaving the remaning portion. This is a workaround for that.

Introduction

In this article, I will explain how to convert a UIELement to a JPEG image and print the UIElement. Silverlight 4 supports printing UIElements. But it will print content only in a single page. If the control's content is big enough to fall in multiple pages, then we cannot get the subsequent pages to print. In this article, I will explain how to get rid of this problem. The simple idea is to convert the UIElement to image. Then splitting the image to multiple pages and sending them to the printer one by one.

Using the code

The first step is to design your XAML.

In this example, I'm going to print the StackPanel called "stkPanel".

<StackPanel x:Name="stkPanel" Orientation="Vertical" Grid.Row="1">
      <Image Source="jawahar.jpg" Width="500" Height="400"/>
 
      <TextBlock Text="Silverlight - Printing a huge control in multiple pages 1"/>
      <TextBlock Text="Silverlight - Printing a huge control in multiple pages 2"/>
      <TextBlock Text="Silverlight - Printing a huge control in multiple pages 3"/>
      <TextBlock Text="Silverlight - Printing a huge control in multiple pages 4"/> </StackPanel>

In the code-behind, inside the Print button event, first convert the UIElement to an image.

ExtendedImage ei = ImageExtensions.ToImage(stkPanel); //stkPanel - Control that you want to print

The next thing we need to do is get the printer's printable area. Then use that to divide the image to multiple pages till it reaches the end of the image.

void pd_PrintPage(object sender, PrintPageEventArgs e)
{
    int printableAreaHeight = Convert.ToInt32(e.PrintableArea.Height);
    int printableAreaWidth = Convert.ToInt32(e.PrintableArea.Width);
    int ActualImageHeight = ei.PixelHeight;
    int ActualImageWidth = ei.PixelWidth;
    int NoOfPages = (ActualImageHeight / printableAreaHeight);
    if ((ActualImageHeight % printableAreaHeight) > 0)
        NoOfPages += 1;
    images = new List<ExtendedImage>();
    ImageTools.Rectangle rt;
    int xCoordinate = 0;
    int yCoordinate = 0;
    int rectangleHeight = 0;
    for (int i = 0; i < NoOfPages; i++)
    {
        if (i > 0)
        {
            yCoordinate = printableAreaHeight * i;
        }
        if ((i + 1) == NoOfPages)
        {
            if ((ActualImageHeight % printableAreaHeight) > 0)
                rectangleHeight = (ActualImageHeight % printableAreaHeight);
            else
                rectangleHeight = printableAreaHeight;
        }
        else
        {
            rectangleHeight = printableAreaHeight;
        }
        rt = new ImageTools.Rectangle(xCoordinate, yCoordinate, 
                 ActualImageWidth, rectangleHeight);
        //slices the image to multiple images(multiple pages) and adds to an images list
        images.Add(ExtendedImage.Crop(ei, rt)); 
    }
 
    var bitmapImage = new BitmapImage();
    bitmapImage.SetSource(images[_currentPage].ToStream());
 
    var imageBrush = new ImageBrush();
    imageBrush.ImageSource = bitmapImage;
    var rectangle = new System.Windows.Shapes.Rectangle
    {
        Width = bitmapImage.PixelWidth,
        Height = bitmapImage.PixelHeight,
        Fill = imageBrush
    };
    e.PageVisual = rectangle; //sets the pagevisual to print
    ++_currentPage;
    if (_currentPage < NoOfPages) //Checks if there are more pages to print
        e.HasMorePages = true;
}

Then start the priniting. Inside the PrintPage event, assign the split image one by one to the PageVisual property of the PrintEventArgs. Set the HasMorePages property to true till it reaches all the pages. Isn't this simple?

In this example, I printed a StackPanel element which contains an image and more than 200 lines of text. If we print this element without my code, only half of the StackPanel gets printed. Using my code will resolve this problem. My code will convert the element to an image and split the image to fit multiple print pages.

Note

In this article, I just gave an idea of how to print a Silverlight UIElement in multiple pages. But you can customize the print view on your own.

History

  • 2nd September, 2011: Initial post.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

jawaharks
Software Developer (Senior) Softura Pvt Ltd
India India
He is currently working as a Silverlight application developer. Has a very good skill over C#, Sharepoint, XAML, Silverlight & WPF.

During his professional career he worked in various technologies in microsoft patform. He never hesitates to take up challenges.

He has completed various microsoft certifications including the latest Sharepoint 2010.
 
He is currently focusing on Sharepoint 2010 and RIA - Silverlight. He is willing to become a technology specialist in Microsoft platform. Hs is always willing to learn new things and like to help others facing technical difficulties.

Specialties: Sharepoint Application Development, Silverlight Application Development
Follow on   Twitter

Comments and Discussions

 
QuestionGive exception in silverlight 5 Pinmemberpsanghvi9-May-13 19:59 
QuestionCrop the image based on control Pinmembernambidasan29-Jan-13 0:30 
GeneralMy vote of 3 PinmemberSivakrishna Reddy13-Sep-12 22:46 
GeneralMy vote of 5 Pinmemberrj_sp4-May-12 1:58 
QuestionI get an error... PinmemberMember 879363513-Apr-12 8:12 
GeneralHi, This is realy nice article and it is working fine for s... PinmemberMember 83775054-Dec-11 6:12 
Generalthnx a lottt Pinmemberd.ban23-Nov-11 3:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 2 Sep 2011
Article Copyright 2011 by jawaharks
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid