打印支持 > 高级打印 |
如果您希望在打印过程中获得更多的控制能力,请使用GetPageImages方法以自动将grid拆分为多张图像,每一张图像将呈现为一个独立的Page。每一张图像都是对grid的某个部分的100%精确呈现,包括央视,自定义元素,在每一页上重复的行头和列头,等等。
GetPageImages方法同样允许调用方缩放该图片,因此整个Grid可以以原始尺寸呈现,缩放以适应单个页面,或者缩放以适应单个页面的宽度。
一旦你得到的页面图像,你可以使用WPF或Silverlight的打印支持将其呈现至文档,您将具有完全的控制灵活性。例如,您可以创建包含多个grid、图表和其他类型内容的文档。您还可以自定义页眉和页脚,添加信笺抬头,等等。
在WPF和Silverlight的打印框架是不同的。一下章节演示应用程序如何在各个平台(WPF和Silverlight)使用GetPageImages方法将C1FlexGrid打印至文档。
和Silverlight相比,在WPF中打印文档需要一个稍微不同的步骤:
下面的代码显示了该机制的示例实现。
C# |
拷贝代码
|
---|---|
// 打印 grid void _btnPrint_Click(object sender, RoutedEventArgs e) { var pd = new PrintDialog(); if (pd.ShowDialog().Value) { // 获取页边距,缩放模式 var margin = 96.0; var scaleMode =; // 获取页面尺寸 var pageSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight); // 创建 paginator var paginator = new FlexPaginator( _flex, ScaleMode.PageWidth, pageSize, new Thickness(margin), 100); // 打印文档 pd.PrintDocument(paginator, "C1FlexGrid printing example"); } } |
FlexPaginator类提供了页面图像,从概念上和Silverlight中使用的PrintPage事件处理相似。实现如下:
C# |
拷贝代码
|
---|---|
/// <summary> /// 用来呈现C1FlexGrid控件的DocumentPaginator类。 /// </summary> public class FlexPaginator : DocumentPaginator { Thickness _margin; Size _pageSize; ScaleMode _scaleMode; List<FrameworkElement> _pages; public FlexPaginator(C1FlexGrid flex, ScaleMode scaleMode, Size pageSize, Thickness margin, int maxPages) { // 保存参数 _margin = margin; _scaleMode = scaleMode; _pageSize = pageSize; // 在构建grid图像之前为页边距调整页面尺寸 pageSize.Width -= (margin.Left + margin.Right); pageSize.Height -= (margin.Top + margin.Bottom); // 获取grid每一页的图像 _pages = flex.GetPageImages(scaleMode, pageSize, maxPages); } |
该构造函数创建页面图像。它们将在稍后再打印framework调用pageinator的GetPage方法时呈现到页面上:
C# |
拷贝代码
|
---|---|
public override DocumentPage GetPage(int pageNumber) { // 创建页面元素 var pageTemplate = new PageTemplate(); // 设置页边距 pageTemplate.SetPageMargin(_margin); // 设置内容 pageTemplate.PageContent.Child = _pages[pageNumber]; pageTemplate.PageContent.Stretch = _scaleMode == ScaleMode.ActualSize ? System.Windows.Media.Stretch.None : System.Windows.Media.Stretch.Uniform; // 设置页脚文本 pageTemplate.FooterRight.Text = string.Format("Page {0} of {1}", pageNumber + 1, _pages.Count); // 排布页面上的元素 pageTemplate.Arrange( new Rect(0, 0, _pageSize.Width, _pageSize.Height)); // 返回新的文档页面 return new DocumentPage(pageTemplate); } |
和Silverlight示例中所展示的一样,一个辅助的PageTemplate类被用作保存grid的图像并提供页边距,页眉和页脚。
paginator上的其它方法提供了简单的实现:
C# |
拷贝代码
|
---|---|
public override int PageCount { get { return _pages.Count; } } public override IDocumentPaginatorSource Source { get { return null; } } public override Size PageSize { get { return _pageSize; } set { throw new NotImplementedException(); } } public override bool IsPageCountValid { get { return true; } } } |
下图展示了当grid呈现到一个XPS文件时,所创建的文档。该图像是非常准确的,包括在样本中使用的自定义rating单元格。行头和列头会自动包含在每一个页面中,同时包含一个简单的页面标题和标准的“Page n of m”页脚。
在Silverlight中打印文档,须遵循以下步骤:
Print方法显示打印对话框。如果用户单击OK,则文档将触发一次BeginPrint事件,接下来为打印每一页触发一次PrintPage事件,最终将在最后一页呈现完毕时触发一个EndPrint事件。下面的代码显示了该机制的示例实现。
我们使用两个变量来保存页面图像并保持跟踪当前打印的页面:
C# |
拷贝代码
|
---|---|
List<FrameworkElement> _pages;
int _currentPage;
|
这里是调用打印文档的处理程序:
C# |
拷贝代码
|
---|---|
// 打印 grid void _btnPrint_Click(object sender, RoutedEventArgs e) { // 创建PrintDocument变量 var pd = new System.Windows.Printing.PrintDocument(); // prepare to print _pages = null; pd.PrintPage += pd_PrintPage; // 打印文档 pd.Print("C1FlexGrid"); } |
PrintPage方法做所有的工作。当第一次被调用时,它将生成全部的页面图像,接下来呈现这些图形至页面。
C# |
拷贝代码
|
---|---|
void pd_PrintPage(object sender, PrintPageEventArgs e) { if (_pages == null) { // 计算页面尺寸,扣除页边距 var sz = e.PrintableArea; sz.Width -= 2 * 96; // one inch left/right margins sz.Height -= 2 * 96; // one inch top/bottom margins // 上下页边距为1英寸 _currentPage = 0; _pages = _flex.GetPageImages(ScaleMode.ActualWidth, sz, 100); } // 创建表示该页面的视觉元素 var pageTemplate = new PageTemplate (); // 应用页边距至页面模版 pageTemplate.SetPageMargin(new Thickness(_margin)); // 添加内容至页面模板 pageTemplate.PageContent.Child = _pages[_currentPage]; // 应用页脚文本 pageTemplate.FooterRight.Text = string.Format("Page {0} of {1}", _currentPage + 1, _pages.Count); // 呈现页面 e.PageVisual = pageTemplate; // 移动到下一页 _currentPage++; e.HasMorePages = _currentPage < _pages.Count; } |
该示例使用一个自定义的辅助类,叫做PageTemplate,而不是将grid图像直接呈现在页面上。
该类提供了页边距,页眉,页脚以及一个host实际grid图像的ViewBox控件。将grid图像直接呈现到页面也能达到同样效果,但是模版增加了很多灵活性。(注意PageTemplate类在示例中实现,其并非属于C1FlexGrid程序集的一部分)。
这里是定义PageTemplate类的XAML代码:
XAML |
拷贝代码
|
---|---|
<Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="96" /> <RowDefinition Height="*"/> <RowDefinition Height="96" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="96"/> <ColumnDefinition Width="*" /> <ColumnDefinition Width="96"/> </Grid.ColumnDefinitions> <!-- header --> <Border Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="0 12" BorderBrush="Black" BorderThickness="0 0 0 1" > <Grid> <TextBlock Text="ComponentOne FlexGrid" FontWeight="Bold" FontSize="14" VerticalAlignment="Bottom" HorizontalAlignment="Left" /> <TextBlock Text="Printing Demo" FontWeight="Bold" FontSize="14" VerticalAlignment="Bottom" HorizontalAlignment="Right" /> </Grid> </Border> <!-- footer --> <Border Grid.Column="1" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0 12" BorderBrush="Black" BorderThickness="0 1 0 0" > <Grid> <TextBlock x:Name="FooterLeft" Text="Today" VerticalAlignment="Bottom" HorizontalAlignment="Left" /> <TextBlock x:Name="FooterRight" Text="Page {0} of {1}" VerticalAlignment="Bottom" HorizontalAlignment="Right" /> </Grid> </Border> <! -- page content --> <Viewbox x:Name="PageContent" Grid.Row="1" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" /></Grid> |