从Silverlight强制进行横向打印?

时间:2011-08-26 16:56:21

标签: silverlight printing

使用Silverlight 4,是否可以横向模式打印网格并显示所有内容?我们将“页面”构建为Grid并从PrintDocument的PrintableArea设置转置的高度/宽度。然后我们应用CompositeTransform来设置Rotation和TranslateX。基本上,它与solution found here非常相似。

这会使内容正确旋转,并且所有出现都会拉伸页面的宽度(在这种情况下是高度),但是底部部分正在被切断。它几乎就像显示到页面正常宽度的内容(通常是8.5“宽度),尽管它被渲染到页面的高度(11”高度)。因此,2.5英寸的内容将作为页面底部的空白内容出现。

注意:我们不会将现有的视觉元素从UI中拉出来放入“页面”网格。我们定义DataTemplates并将VM传递给DataContext。所有内容都被正确绑定和显示,但是对打印文档的渲染是出错的。

我们缺少什么?我们希望避免首先渲染页面的位图,但如果这是我们必须做的......

更新:根据进一步调查(并与开始处理报告的团队成员交谈),代码基于Pete Brown's client side printing。我们对分组和增强报告的功能进行了一些扩展,但整体布局处理是相同的引擎。

如果你看一下Pete Brown的代码,我们正在使用的当前差异是GetNewPage方法中的以下内容:

    ...
    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);
    ...

这可以很好地自动旋转内容,但宽度仍然被切断,就像它将页面宽度仍然像肖像一样。即使我已经改变了要交换的所有测量值。似乎调用InvalidateMeasure()InvalidateArrangement()对更改输出没有任何影响。奇怪的是,当我将ScaleX更改为大于1的内容时,它会拉伸剪切的内容以填充更多页面。所以它几乎就像父容器在转换之前被剪切一样,尽管代码说明不然。基本上它似乎是Shawn Wildermuth blogged about的剪辑。所以我仍然在寻找想法/解决方案......

3 个答案:

答案 0 :(得分:2)

使用canvas容器控件,旋转控件在画布内

经过几个小时的纯粹挫折之后,我终于决定把东西放在画布里面。瞧!不再切断。

看看下面的SMALL测试应用程序来演示。它只是一个带打印按钮的页面。

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;
        }
    }
}

如果删除外部画布,则会导致页面显示为剪切,就像仍在打印肖像一样。

答案 1 :(得分:1)

如果没有任何基本的Xaml,很难确定问题是什么。但是我要去这里打一场。

您正在使用RenderTransform,但应用变换的元素将向其容器报告原始未变换的尺寸。结果,容器根据该信息进行裁剪。

我建议解决方案是在您的应用程序中特别包含Silverlight Toolkit LayoutTransformer控件。将包含的页面放在此控件中。然后,LayoutTransformer会在其CompositeTransform媒体资源中接受您的LayoutTransform。这里的区别在于LayoutTransformer报告是在应用转换后的维。因此它的容器不应该夹住它。

答案 2 :(得分:0)

我一直在为同样的问题而战,对我来说,我找到了答案。我一直在网上搜索。这是我找到答案的论坛帖子的链接 - http://forums.silverlight.net/t/237438.aspx/1?how+to+print+landscape+using+SL+print+API+

作者确实有这个家伙的答案。秘密似乎是在调用 InvalidateArrange InvalidateMeasure (哦,并将内容设置为拉伸)......