Windows App支援将UI界面進行列印的功能,這與浏覽器中的列印網頁的用途相近,其好處就是“所見即所得”,直接把界面上呈現的内容列印下來,比重新建立列印圖像友善得多。
要在通用App中實作列印,主要依靠以下幾個類型:
PrintManager:位于Windows.Graphics.Printing命名空間,主要負責顯示列印對話框,設定列印源等操作。在使用時,首先調用GetForCurrentView靜态方法得到一個PrintManager執行個體;随後處理它的PrintTaskRequested,當要進行列印時就會發生該事件。
PrintTask:表示一個列印任務。在PrintManager對象的PrintTaskRequested事件進行中建立列印任務。
PrintDocument:這個類比較關鍵(位于Windows.UI.Xaml.Printing命名空間)。通過它可以将UI元素轉換為待列印的文檔邏輯。a、處理Paginate事件,以計算列印的分頁,計算後可以調用PrintDocument.SetPreviewPageCount方法來設定預覽頁面的總數。b、處理GetPreviewPage事件,當請求預覽單個頁面時會發生該事件,在處理過程中,可以調用PrintDocument.SetPreviewPage方法來設定要預覽的特定頁面。c、當開始列印時,會發生AddPages事件,此時調用PrintDocument.AddPage方法向列印文檔邏輯添加頁面,當所有要列印的頁面都添加完畢後,請調用AddPagesComplete方法通知系統可以送出列印了。
當你剛剛接觸列印時,你會覺得它好像很複雜,其實,當你動手做過實驗後,你就會發現,其實也沒什麼。我們作為新時代的開發者,應當有迎難而上的精神。
下面咱們來做個例子,把頁面上的一個RichTextBlock控件中的内容列印出來。
頁面上的XAML大緻如下,老周直接貼出來,不作解釋了,我相信你能看懂XAML,如果看不懂,那就算了。
<Border Padding="30" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<StackPanel Margin="0,15" Orientation="Horizontal">
<Button Content="開始列印" Click="OnClick"/>
</StackPanel>
<RichTextBlock Name="tb" Grid.Row="1" Width="300" >
<Paragraph FontSize="36" TextAlignment="Center" FontFamily="楷體">
床前明月光,
<LineBreak/>
疑是地上霜。
<LineBreak/>
舉頭望明月,
<LineBreak/>
低頭思故鄉。
</Paragraph>
<Paragraph TextAlignment="Center">
<InlineUIContainer>
<Image Height="200" Source="http://img155.poco.cn/mypoco/myphoto/20110305/15/20110305154657_366496406.gif"/>
</InlineUIContainer>
</Paragraph>
</RichTextBlock>
……
</Grid>
</Border>
咱們這例子要列印的内容,就是那個名為tb的家夥。
進入頁面的代碼檔案,在頁面類中聲明以下字段:
PrintManager printmgr = PrintManager.GetForCurrentView();
PrintDocument printDic = null;
RotateTransform rottrf =null;
PrintTask task = null;
RotateTransform變量的作用是把tb進行旋轉變換,這是為了處理列印頁面的方向,如果頁面是橫向,我就把tb轉90度。
處理PrintManager的PrintTaskRequested事件,建立列印任務,并設定列印源。
printmgr.PrintTaskRequested += Printmgr_PrintTaskRequested;
……
private void Printmgr_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
var def = args.Request.GetDeferral();
// 建立列印任務
task = args.Request.CreatePrintTask("列印測試", OnPrintTaskSourceRequrested);
task.Completed += Task_Completed;
def.Complete();
}
在調用CreatePrintTask方法建立列印任務時,有一個參數需要通過一個委托來設定列印源。所謂列印源,就是我們要列印的文檔。
private async void OnPrintTaskSourceRequrested(PrintTaskSourceRequestedArgs args)
{
var def = args.GetDeferral();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
() =>
{
// 設定列印源
args.SetSource(printDic?.DocumentSource);
});
def.Complete();
}
我們這裡要列印的其實就是PrintDocument對象,我們變量命名好像錯了,叫printDoc合理一些,我打成了printDic。沒事,大家知道就OK了。
下面代碼處理按鈕的單擊事件:
private async void OnClick(object sender, RoutedEventArgs e)
{
if (printDic != null)
{
printDic.GetPreviewPage -= OnGetPreviewPage;
printDic.Paginate -= PrintDic_Paginate;
printDic.AddPages -= PrintDic_AddPages;
}
this.printDic = new PrintDocument();
printDic.GetPreviewPage += OnGetPreviewPage;
printDic.Paginate += PrintDic_Paginate;
printDic.AddPages += PrintDic_AddPages;
// 顯示列印對話框
bool b=await PrintManager.ShowPrintUIAsync();
}
在執行個體化PrintDocument後,要處理它的幾個事件。
先處理AddPages事件,這個事件是在開始執行列印時才會發生,在事件進行中要向列印文檔添加頁面,每個頁面的内容就是我們要列印的UI元素,為了簡單,老周隻列印一頁。
private void PrintDic_AddPages(object sender, AddPagesEventArgs e)
{
// 添加要列印的頁
printDic.AddPage(tb);
// 報告添加完成
printDic.AddPagesComplete();
}
處理Paginate事件,這個事件在打開列印對話框時發生,并且如果使用者調整了列印對話框中的參數後也會發生(比如修改了頁面方向),目的是重新計算頁面的預覽。
private void PrintDic_Paginate(object sender, PaginateEventArgs e)
{
PrintTaskOptions opt = task.Options;
// 根據頁面的方向來調整列印内容的旋轉方向
switch (opt.Orientation)
{
case PrintOrientation.Default:
rottrf.Angle = 0d;
break;
case PrintOrientation.Portrait:
rottrf.Angle = 0d;
break;
case PrintOrientation.Landscape:
rottrf.Angle = 90d;
break;
}
// 設定預覽頁面的總頁數
printDic.SetPreviewPageCount(1, PreviewPageCountType.Final);
}
下面代碼添加特定頁面的預覽。
private void OnGetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
// 設定要預覽的頁面
printDic.SetPreviewPage(e.PageNumber, this.tb);
}
大家要注意,頁面預覽和實際列印是兩回事,是以SetPreviewPage隻是設定要預覽的UI元素,而實際列印是要在AddPages事件中通過AddPage方法來添加頁面。
當示例完成之時,大家可能又遇到問題了,我沒有列印機,怎麼辦? 沒事,老周很窮,也沒有列印機,但不要忘記,系統裡面有這些功能:
是啊,有它們就行,搜尋“裝置與列印機”就能找到它們,是以在運作示例後,直接把内容列印為.pdf文檔就可以了,列印完後,.pdf檔案存到“文檔”目錄中。
現在運作應用程式,然後點選“開始列印”按鈕。
然後會彈出列印對話框。
确認開始列印,點選“列印”按鈕。列印完成後系統會以Toast通知來提醒你。下圖所示是列印出來的.pdf檔案。
好了,是不是有點高大上的感覺呢?
示例代碼下載下傳:https://files.cnblogs.com/files/tcjiaan/printSample.zip