Customize landscape printing from Silverlight?

Using Silverlight 4, can I print the grid in landscape mode and show all the contents? We create the “page” as a Grid and set the transposed height / width from the PrintDocument PrintableArea. Then we use CompositeTransform to set Rotation and TranslateX. Essentially, this is very similar to the solution found here .

This allows the content to rotate properly, and everything seems to stretch the width (well, height in this case) of the page, but the bottom is cropped. This is almost similar to content displayed at the normal page width (usually 8.5 "), although it was displayed at the height of the page (11 inches tall). Thus, 2.5 inches of content appears as empty content at the bottom of the page .

Note. We do not pull the existing visual element from the user interface to place it in the "page". We define DataTemplates and pass the VM to the DataContext. All content is tied and displayed correctly, as far as possible, but rendering in a printed document is what happens wrong.

Is there something we are missing? We hope to avoid having to display the bitmap of the page first, but if that's what we should do ...

UPDATE: Based on further investigation (and talking with the guy on the team that started working on the reports), the code is very heavily based on Print on the client side of Pete Brown . We expanded it a little to group and improve the report functions, but in general, layout processing is the same engine.

If you look at the Pete Brown code, the current difference we are using is the following in the GetNewPage method:

  ... this.CurrentPageNumber++; Grid pagePanel = new Grid(); LayoutTransformer layoutTransformer = new LayoutTransformer { Content = pagePanel, Tag = this.CurrentPageNumber }; if (printableArea.Height > printableArea.Width) { // printable area is in Portrait mode. layoutTransformer.Height = printableArea.Width; layoutTransformer.Width = printableArea.Height; var transform = new CompositeTransform { Rotation = 90, TranslateX = printableArea.Width, ScaleX = 1, ScaleY = 1 }; layoutTransformer.LayoutTransform = transform; layoutTransformer.ApplyLayoutTransform(); layoutTransformer.RenderTransform = transform; } else { // printable area is in Landscape mode layoutTransformer.Height = printableArea.Height; layoutTransformer.Width = printableArea.Width; } Size pageSize = new Size(layoutTransformer.Width, layoutTransformer.Height); layoutTransformer.HorizontalAlignment = HorizontalAlignment.Stretch; layoutTransformer.VerticalAlignment = VerticalAlignment.Stretch; RowDefinition headerRow = new RowDefinition { Height = GridLength.Auto }; RowDefinition itemsRow = new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }; RowDefinition footerRow = new RowDefinition { Height = GridLength.Auto }; pagePanel.RowDefinitions.Add(headerRow); pagePanel.RowDefinitions.Add(itemsRow); pagePanel.RowDefinitions.Add(footerRow); ... 

This works great when automatically rotating content, but the width is still chopped off, as if it makes the page width more like a portrait. Despite the fact that I changed all the dimensions that need to be interchanged. It seems that calls to InvalidateMeasure() and InvalidateArrangement() have no meaning to change the output. The strange thing is that when I change ScaleX to something larger than 1, it stretches the cropped content to fill most of the page. Thus, almost like the parent container is truncated before the conversion, even though the code says otherwise. It basically looks like the clipping that Shawn Wildermuth's blog posted about . So I'm still looking for ideas / solutions ...

+4
source share
3 answers

It's hard to be sure what the problem is without any elementary Xaml. However, I am going to go to punt here.

You are using RenderTransform, but the element on which the transformation is applied will tell the container the original unallocated dimensions. As a result, the container is cut off based on this information.

I suggest that the solution include the Silverlight Toolkit in your application, namely the LayoutTransformer control. Place the contents of the page inside this control. LayoutTransformer will then accept your CompositeTransform in the LayoutTransform property. The difference here in LayoutTransformer reports is the dimensions after applying the transform. Therefore, its container should not clamp it.

+1
source

Use the canvas container container and rotate the control inside the canvas .

After many hours of sheer disappointment, I finally decided to put the thing on canvas. Voila !! No longer clipped.

Take a look at the following SMALL test application for a demo. This is just a page with a print button. A.

 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 delete the external canvas, this will cause the page to be turned off as if it were in a portrait.

+2
source

I struggled with this very problem, and for me I found the answer. I am combing the internet. Here is a link to a forum post where I found my answer - http://forums.silverlight.net/t/237438.aspx/1?how+to+print+landscape+using+SL+print+API+

The author really has a guy with the answer. The secret seems to be to call InvalidateArrange and InvalidateMeasure (oh, and setting your content to stretch) ...

0
source

Source: https://habr.com/ru/post/1369198/


All Articles