使用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的剪辑。所以我仍然在寻找想法/解决方案......
答案 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 (哦,并将内容设置为拉伸)......