Subscribe to:

The Kiwi's TaleWitchBlasterDerelict Blow Stuff Up

Easy landscape printing in Silverlight

I know this isn't normally what I post about here, but I thought someone on the web might find it useful.

I struggled in vain to find a simple solution to printing landscape view in Silverlight, but I managed to come up with one that only takes a few lines of code:

 

 

            var printDocument = new PrintDocument();

            printDocument.PrintPage += (s, r) =>

                                           {

                                               r.PageVisual = this.LayoutRoot;

                                               var transformGroup = new TransformGroup();

                                               transformGroup.Children.Add(new RotateTransform(){Angle = 90});

                                               transformGroup.Children.Add(new TranslateTransform() {X = r.PrintableArea.Width});

                                               LayoutRoot.RenderTransform = transformGroup;

                                           };

This simple Lamda method, which assumes that you want to print the layout root of the page (Although there shouldn't be a reason why it can't print any element on the page), applies two transforms. The first is simply to rotate the whole layout root 90 degrees. The reason why this alone isn't enough, is that by default the layout root will rotate on it's top left corner, so when you rotate it 90 degrees the body of the page moves left (Imagine rotating a page on a cork board with a pin through the top left corner). The second transform is to correct this by moving the page by the width of the printable area to the right.

After you have finished printing, you will want to move everything back so that it still renders to screen correctly.

 

            printDocument.EndPrint += (s, r) =>

                                          {

                                              var transformGroup = new TransformGroup();

                                              transformGroup.Children.Add(new RotateTransform() { Angle = 0 });

                                              transformGroup.Children.Add(new TranslateTransform() { X = 0});

                                              LayoutRoot.RenderTransform = transformGroup;

                                          };

Hope this helps

 

EDIT: Martin Lottering has offered the suggestion below for resolving an issue where the sides of the page may be cut off:

If you battle to get the landscape printing working properly because it cuts off:

Use a `canvas` container control, and **rotate** the control **inside of the canvas**.

After many hours of pure frustration, I finally decided to put the thing inside of a canvas. Voila!! No more cut off.

Have a look at the following SMALL test application to demonstrate. It is just a page with print button.

 

    using System.Windows;

    using System.Windows.Controls;

    using System.Windows.Media;

    using System.Windows.Printing;

    using System.Windows.Shapes;

 

    namespace SilverlightApplication1 {

 

        public partial class MainPage : UserControl {

 

            public MainPage() {

                InitializeComponent();

            }

 

            private void Button_Click_1(object sender, RoutedEventArgs e) {

                PrintDocument PD = new PrintDocument();

                PD.PrintPage += PD_PrintPage;

                PD.Print("Print Test");

            }

 

            void PD_PrintPage(object sender, PrintPageEventArgs e) {  

                Canvas OuterCanvas = new Canvas();

                /* a container for everything that will print */

                Border OuterBorder = new Border() {

                    BorderThickness = new Thickness(3),

                    BorderBrush = new SolidColorBrush(Colors.Red),

                    Margin = new Thickness(10)

                };   

 

                double Width = e.PrintableArea.Width - OuterBorder.Margin.Left - OuterBorder.Margin.Right;

                double Height = e.PrintableArea.Height - OuterBorder.Margin.Top - OuterBorder.Margin.Bottom;

                /* NOTE: We're trying to force landscape, so swop the width and height */

                OuterBorder.Width = Height;

                OuterBorder.Height = Width;

                /* on portrait, this line goes down (leave the printer settings, we're trying to force landscape) */

                Line Line = new Line() {

                    X1 = OuterBorder.Width / 2,

                    Y1 = 0,

                    X2 = OuterBorder.Width / 2,

                    Y2 = OuterBorder.Height,

                    Stroke = new SolidColorBrush(Colors.Blue),

                    StrokeThickness = 3

                };

                OuterBorder.Child = Line;

                OuterCanvas.Children.Add(OuterBorder);

 

                /* rotate 90 degrees, and move into place */

                var transformGroup = new TransformGroup();

                transformGroup.Children.Add(new RotateTransform() { Angle = 90 });

                transformGroup.Children.Add(new TranslateTransform() { X = e.PrintableArea.Width });

                OuterBorder.RenderTransform = transformGroup;

                e.PageVisual = OuterCanvas;

                e.HasMorePages = false;

            }

        }

    }

If you don't put the border inside of a canvas, it causes the page to appear cut off as if still printing portrait.


Tags:

Comments

Martin Lottering (not verified)

Thanks, it helped a lot. 

admin
Offline
Joined: 02/05/2009

No problem, thanks for leaving a comment :)

Martin Lottering (not verified)

 

 

May I add a small suggestion?
 
If you battle to get the landscape printing working properly because it cuts off:
 
Use a `canvas` container control, and **rotate** the control **inside of the canvas**.
 
 
After many hours of pure frustration, I finally decided to put the thing inside of a canvas. Voila!! No more cut off.
 
 
Have a look at the following SMALL test application to demonstrate. It is just a page with print button.
 
 
 
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Printing;
    using System.Windows.Shapes;
 
    namespace SilverlightApplication1 {
 
        public partial class MainPage : UserControl {
 
            public MainPage() {
 
                InitializeComponent();
 
            }
 
    
 
            private void Button_Click_1(object sender, RoutedEventArgs e) {
 
                PrintDocument PD = new PrintDocument();
 
                PD.PrintPage += PD_PrintPage;
 
                PD.Print("Print Test");
 
            }
 
    
 
            void PD_PrintPage(object sender, PrintPageEventArgs e) {  
 
                Canvas OuterCanvas = new Canvas();
 
 
                /* a container for everything that will print */
 
                Border OuterBorder = new Border() {
 
                    BorderThickness = new Thickness(3),
 
                    BorderBrush = new SolidColorBrush(Colors.Red),
 
                    Margin = new Thickness(10)
 
                };   
 
                double Width = e.PrintableArea.Width - OuterBorder.Margin.Left - OuterBorder.Margin.Right;
 
                double Height = e.PrintableArea.Height - OuterBorder.Margin.Top - OuterBorder.Margin.Bottom;
  
 
                /* NOTE: We're trying to force landscape, so swop the width and height */
 
                OuterBorder.Width = Height;
 
                OuterBorder.Height = Width;
 
 
                /* on portrait, this line goes down (leave the printer settings, we're trying to force landscape) */
 
                Line Line = new Line() {
 
                    X1 = OuterBorder.Width / 2,
 
                    Y1 = 0,
 
                    X2 = OuterBorder.Width / 2,
 
                    Y2 = OuterBorder.Height,
 
                    Stroke = new SolidColorBrush(Colors.Blue),
 
                    StrokeThickness = 3
 
                };
 
                OuterBorder.Child = Line;
 
                OuterCanvas.Children.Add(OuterBorder);
 
 
                /* rotate 90 degrees, and move into place */
 
                var transformGroup = new TransformGroup();
 
                transformGroup.Children.Add(new RotateTransform() { Angle = 90 });
 
                transformGroup.Children.Add(new TranslateTransform() { X = e.PrintableArea.Width });
 
                OuterBorder.RenderTransform = transformGroup;
 
                e.PageVisual = OuterCanvas;
 
                e.HasMorePages = false;
 
            }
        }
    }
 
 
If you don't put the border inside of a canvas, it causes the page to appear cut off as if still printing portrait.
Regards,
Martin

 

admin
Offline
Joined: 02/05/2009

Excellent suggestion. I don't use Silverlight much myself any more but since this is one of the most widely viewed pages on my site someone will get some use out of it. I'll paste it into the body of the post.

Job Interview (not verified)

I used to be able to find good information from your
content.

Guillermo Valls MARCA (not verified)

Awesome! Its genuinely remarkable article, I have
got much clear idea about from this paragraph.

I'm no longer sure where you're getting your information, however good topic.

I must spend some time finding out more or figuring out more.

Thanks for great information I was on the lookout for this information for my mission.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
  • HTML tags will be transformed to conform to HTML standards.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.