Click here to Skip to main content
15,881,139 members
Articles / General Programming / Printing
Tip/Trick

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

Rate me:
Please Sign up or sign in to vote.
4.33/5 (3 votes)
2 Sep 2011CPOL2 min read 34.8K   906   1   7
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".


XML
<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.


C#
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.


C#
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)


Written By
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

Comments and Discussions

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

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

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