介紹
重新想象 Windows 8 Store Apps 之 打印
示例
1、需要打印的文檔
Print/PrintPage.xaml
<Page
x:Class="XamlDemo.Print.PrintPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Print"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<!--
需要打印的文檔
-->
<Grid x:Name="printableArea">
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="4*"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*" />
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<!--頁頭,僅第一頁需要頁頭-->
<StackPanel x:Name="header" Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2" Height="60" Visibility="Collapsed">
<Image Source="ms-appx:///Assets/Logo.png" HorizontalAlignment="Left"/>
<RichTextBlock Foreground="Black" FontSize="20" TextAlignment="Left" Margin="10 0 0 0">
<Paragraph>webabcd print demo</Paragraph>
</RichTextBlock>
</StackPanel>
<!--正文-->
<RichTextBlock Foreground="Black" x:Name="textContent" FontSize="18" Grid.Row="1" Grid.ColumnSpan="2" TextAlignment="Left" VerticalAlignment="Top" HorizontalAlignment="Left"
OverflowContentTarget="{Binding ElementName=imageLeftText}">
<Paragraph FontSize="32">Microsoft</Paragraph>
<Paragraph></Paragraph>
<Paragraph TextIndent="36">微軟(Microsoft,NASDAQ:MSFT,HKEx: 4338)公司是世界
PC(Personal Computer,個人計算機)機軟件開發的先導,由比爾·蓋茨與保羅·艾倫創始於1975年,總部設
在華盛頓州的雷德蒙市(Redmond,鄰近西雅圖)。目前是全球最大的電腦軟件提供商。微軟公司現有雇員9萬
人,2012年營業額699.4億美元,其主要產品為Windows操作系統、Internet Explorer網頁浏覽器及Microsoft
Office辦公軟件套件。1999年推出了MSN Messenger網絡即時信息客戶程序;2001年推出Xbox游戲機,參與游
戲終端機市場競爭。2012年8月23日,微軟25年以來首次更換公司Logo。</Paragraph>
<Paragraph></Paragraph>
<Paragraph TextIndent="36">2001年,微軟結合Windows 98和Windows 2000系列的優點
,推出了Windows XP操作系統,XP的意思是“體驗”。XP系統重點加強了安全性和穩定性,首次在Windows操
作系統中集成了微軟自己的防火牆產品。它還拓展了多媒體應用方面的功能。XP系統主要有家庭版和專業版兩
種,其中專業版保留了Windows 2000中的用戶管理、組策略等安全特性,並使其更加易用。Windows XP又一次
成為軟件發展史上的經典之作。</Paragraph>
<Paragraph></Paragraph>
<Paragraph TextIndent="36">在IT軟件行業流傳著這樣一句告誡:“永遠不要去做微軟
想做的事情”。可見,微軟的巨大潛力已經滲透到了軟件界的方方面面,簡直是無孔不入,而且是所向披靡。
微軟的巨大影響已經對軟件同行構成了極大的壓力,也把自己推上了反壟斷法的被告位置。連多年來可靠的合
作伙伴Intel也與之反目,對簿公堂。2001年9月,鑒於經濟低迷,美國政府有意重振美國信息產業,拒絕拆分
微軟。至此,訴微軟反壟斷法案告一段落。</Paragraph>
<Paragraph></Paragraph>
<Paragraph TextIndent="36">微軟聯合創始人兼領袖比爾·蓋茨、保羅·艾倫,兩位都
是世界上智力過人,才華出眾的天才。保羅·艾倫的智力商數超越170, 在當微軟創始人之一 比爾·蓋茨今
世界的天才中排名第九, 比爾蓋茨智商超越160,曾經在哈佛大學讀書期間,數學成績十分突出,解決過一道
世界難題,受美國科學院院士哈佛教授嘉獎,並與老師聯合發表論文。 現任總裁史蒂夫·鮑爾默曾是美國數
學競賽全美前10名,美國高考SAT考試,保羅·艾倫與史蒂夫·鮑爾默更是獲得了1600分的滿分。
</Paragraph>
<Paragraph></Paragraph>
<Paragraph TextIndent="36">Xbox360是世界最大的電腦軟件公司微軟所開發的第二代家
用視頻游戲主機,在開發時被稱為“Xenon”、“Xbox 2”及“Xbox Next”等。微軟Xbox360是唯一一款具備
定時功能的游戲機,家長們可輕松設定相應游戲時間,同時也能對孩子們所玩、所觀看的內容加以限制。Xbox
Live誕生於2002年,是微軟為其游戲主機XBOX所提供的網絡服務。聯機游戲:支持語音短信、私人語音聊天、
個性化設置以及統一標准的好友列表。2001年公司推出的Xbox游戲機標志著公司開始進入價值上百億美元的游
戲終端市場,這個市場之前一直由索尼公司(Sony)和任天堂(Nintendo)兩家公司主導。2005年11月22日,
微軟公司發售第二代家用視頻游戲主機Xbox360。</Paragraph>
<Paragraph></Paragraph>
<Paragraph TextIndent="36">北京時間5月22日消息,據微軟官網和路透社報道,微軟5
月21日正式發布了新一代的游戲主機Xbox One,微軟將其定義為多功能一體的游戲和娛樂系統,強調融合TV和
游戲的全娛樂體驗。本次發布距微軟2005年發布上一代Xbox 360以來,已經時隔8年。微軟在華盛頓州雷德蒙
德市的公司總部演示了Xbox One如何將用戶置於所有的游戲、電視、電影、音樂、體育和Skype的中心。微軟
互動娛樂業務總裁唐·馬特裡克(Don Mattrick)稱:“Xbox One目的是在一個強大的多功能一體設備中提供全
新一代的強大的游戲、電視和娛樂。我們的獨特的現代的架構將首次給客廳帶來簡單化,帶來在游戲和娛樂之
間即時進行轉換的能力。”</Paragraph>
<Paragraph></Paragraph>
<Paragraph TextIndent="36">新一代 Kinect 將視頻攝影解析度提高到 1080p,視角較
前一代寬闊 60 %,深度偵測改採更精確的 Time of Flight(TOF)技術,通過發射與感測紅外線反射的時間
來建構場景的深度資訊,連衣服的皺褶凹凸都能掌握,搭配可見光與紅外線兩組感測器,提供不受環境光線影
響的感測能力。借由更精確的深度資訊,新一代 Kinect 得以更精確掌握人體關節的運動,連大拇指與手掌的
開合都能判斷。不只是姿勢,還可以通過模擬計算來掌握肌肉的施力與重心的轉移。可以通過脈搏所造成的膚
下血管反射可見光與紅外線變化來掌握脈搏,具備臉部辨識與表情判斷的能力。新一代 Kinect 除了反應更快
速、偵測更精確之外,同時感測人數也從前一代的最多2人擴增為最多6人,還可以根據臉部辨識來掌握不同玩
家的所在位置,提供多人同樂更多的可能性。</Paragraph>
</RichTextBlock>
<RichTextBlockOverflow x:Name="imageLeftText" OverflowContentTarget="{Binding
ElementName=textOverflow}" Grid.Row="2" Grid.Column="0"/>
<Image Source="ms-appx:///Assets/Logo.png" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="1" Margin="10"/>
<RichTextBlockOverflow x:Name="textOverflow" Grid.Row="3" Grid.ColumnSpan="2"/>
<!--頁腳,僅最後一頁需要頁腳-->
<StackPanel x:Name="footer" Orientation="Horizontal" Grid.Row="4" Grid.Column="0" Height="60" Visibility="Collapsed">
<Image Source="ms-appx:///Assets/Logo.png" HorizontalAlignment="Left" />
<RichTextBlock Foreground="Black" FontSize="16" TextAlignment="Left" Margin="10 0 0 0">
<Paragraph>http://webabcd.cnblogs.com/</Paragraph>
</RichTextBlock>
</StackPanel>
</Grid>
</Page>
2、需要打印的文檔的溢出內容
Print/ContinuationPage.xaml
<Page
x:Class="XamlDemo.Print.ContinuationPage"
IsTabStop="false"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Print"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<!--
需要打印的文檔的溢出內容
-->
<Grid x:Name="printableArea">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!--正文-->
<RichTextBlockOverflow x:Name="textOverflow" Grid.Row="0" Grid.Column="0"></RichTextBlockOverflow>
<!--頁腳,僅最後一頁需要頁腳-->
<StackPanel x:Name="footer" Orientation="Horizontal" Grid.Row="4" Grid.Column="0" Height="60" Visibility="Collapsed">
<Image Source="ms-appx:///Assets/Logo.png" HorizontalAlignment="Left" />
<RichTextBlock Foreground="Black" FontSize="16" TextAlignment="Left" Margin="10 0 0 0">
<Paragraph>http://webabcd.cnblogs.com/</Paragraph>
</RichTextBlock>
</StackPanel>
</Grid>
</Page>
Print/ContinuationPage.xaml.cs
using Windows.UI.Xaml.Controls;
namespace XamlDemo.Print
{
public sealed partial class ContinuationPage : Page
{
public ContinuationPage()
{
this.InitializeComponent();
}
// 指定溢出內容的顯示框
public ContinuationPage(RichTextBlockOverflow text)
{
this.InitializeComponent();
text.OverflowContentTarget = textOverflow;
}
}
}
3、演示如何打印文檔
Print/Demo.xaml
<Page
x:Class="XamlDemo.Print.Demo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Print"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<StackPanel Margin="120 0 0 0">
<Button Name="btnPrint" Content="print" Click="btnPrint_Click" />
<!--
printingRoot 保存的是發送到打印機的打印內容
本例的打印內容來自 PrintPage.xaml,溢出內容來自 ContinuationPage.xaml
-->
<Canvas x:Name="printingRoot" Opacity="0" />
</StackPanel>
</Grid>
</Page>
Print/Demo.xaml.cs
/*
* 演示如何打印文檔
*
* 注:
* 本例中 previewPages 保存的是打印預覽頁,xaml 中的 printingRoot 保存的是發送到打印機的打印內容
* 本例的打印內容來自 PrintPage.xaml,溢出內容來自 ContinuationPage.xaml
*/
using System;
using System.Collections.Generic;
using Windows.Graphics.Printing;
using Windows.Graphics.Printing.OptionDetails;
using Windows.UI.Core;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Printing;
namespace XamlDemo.Print
{
public sealed partial class Demo : Page
{
// PrintDocument - 用於提供打印功能
private PrintDocument printDocument = null;
// 打印預覽頁集合
private List<FrameworkElement> previewPages = new List<FrameworkElement>();
// 需要打印的頁
private FrameworkElement printPage;
public Demo()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// 為打印做好准備工作
RegisterForPrinting();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// 釋放為打印所准備的資源
UnregisterForPrinting();
}
private async void btnPrint_Click(object sender, RoutedEventArgs e)
{
// 請求打印,即彈出打印設備列表。注:需要在這之前調用PrintManager.GetForCurrentView();
await PrintManager.ShowPrintUIAsync();
}
// 為打印做好准備工作
private void RegisterForPrinting()
{
printDocument = new PrintDocument();
// 當系統請求將打印內容顯示在預覽窗口時
printDocument.Paginate += printDocument_Paginate;
// 當系統請求將打印內容中的某一頁顯示在預覽窗口時
printDocument.GetPreviewPage += printDocument_GetPreviewPage;
// 當系統請求將打印內容發送到打印機時
printDocument.AddPages += printDocument_AddPages;
// 單擊 charm 中的“設備”後顯示打印設備
PrintManager printManager = PrintManager.GetForCurrentView();
// 當出現打印請求時(在 PrintManager.GetForCurrentView() 之後單擊“設備”彈出打印設備列表時,或通過 PrintManager.ShowPrintUIAsync() 彈出打印設備列表時)
printManager.PrintTaskRequested += printManager_PrintTaskRequested;
// 提供打印內容
PreparedPrintContent();
}
// 釋放為打印所准備的資源
private void UnregisterForPrinting()
{
if (printDocument == null)
return;
printDocument.Paginate -= printDocument_Paginate;
printDocument.GetPreviewPage -= printDocument_GetPreviewPage;
printDocument.AddPages -= printDocument_AddPages;
PrintManager printManager = PrintManager.GetForCurrentView();
printManager.PrintTaskRequested -= printManager_PrintTaskRequested;
printingRoot.Children.Clear();
}
// 提供打印內容
private void PreparedPrintContent()
{
if (printPage == null)
{
printPage = new PrintPage();
StackPanel header = (StackPanel)printPage.FindName("header");
header.Visibility = Visibility.Visible;
}
// 向 printingRoot 添加一個打印內容,以便發送到打印機打印
printingRoot.Children.Add(printPage);
printingRoot.InvalidateMeasure();
printingRoot.UpdateLayout();
}
// 當出現打印請求時,即彈出打印設備列表時
private void printManager_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs e)
{
// 創建一個打印任務
PrintTask printTask = null;
printTask = e.Request.CreatePrintTask("打印任務的標題", async sourceRequested =>
// 在打印設備列表中選擇了某個打印機時
{
// 打印預覽頁中的選項
PrintTaskOptionDetails optionDetails = PrintTaskOptionDetails.GetFromPrintTaskOptions(printTask.Options);
IList<string> displayedOptions = optionDetails.DisplayedOptions;
// 在打印預覽頁上添加系統內置支持的選項
displayedOptions.Clear();
displayedOptions.Add(StandardPrintTaskOptions.Copies);
displayedOptions.Add(StandardPrintTaskOptions.Orientation);
displayedOptions.Add(StandardPrintTaskOptions.MediaSize);
displayedOptions.Add(StandardPrintTaskOptions.Collation);
displayedOptions.Add(StandardPrintTaskOptions.Duplex);
printTask.Options.MediaSize = PrintMediaSize.NorthAmericaLegal;
// 在打印預覽頁上添加自定義選項
PrintCustomItemListOptionDetails pageFormat = optionDetails.CreateItemListOption("CustomOption", "自定義選項"); // 第1個參數:optionId;第2個參數:displayName
pageFormat.AddItem("item1", "選項1"); // 第1個參數:itemId;第2個參數:displayName
pageFormat.AddItem("item2", "選項2");
pageFormat.AddItem("item3", "選項3");
displayedOptions.Add("CustomOption");
optionDetails.OptionChanged += printDetailedOptions_OptionChanged; // 當打印預覽頁中的自定義選項的選中項發生變化時
// 告訴打印任務需要打印的內容
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
sourceRequested.SetSource(printDocument.DocumentSource);
});
// 當打印任務完成時
printTask.Completed += async (s, args) =>
{
if (args.Completion == PrintTaskCompletion.Failed)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
});
}
};
});
}
// 當打印預覽頁中的自定義選項的選中項發生變化時
private async void printDetailedOptions_OptionChanged(PrintTaskOptionDetails sender, PrintTaskOptionChangedEventArgs args)
{
// 獲取發生變化的自定義選項的 OptionId
string optionId = args.OptionId as string;
if (string.IsNullOrEmpty(optionId))
return;
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
MessageDialog messageDialog = new MessageDialog(optionId, "OptionId");
await messageDialog.ShowAsync();
// 獲取打印預覽頁中的指定的自定義選項的選中項的 ItemId
string itemId = sender.Options[optionId].Value as string;
messageDialog = new MessageDialog(itemId, "ItemId");
await messageDialog.ShowAsync();
/*
* 此處需要根據用戶的選擇,來修改打印的內容,這裡就不寫了
*/
// 刷新預覽頁
printDocument.InvalidatePreview();
});
}
// 當系統請求將打印內容顯示在預覽窗口時
private void printDocument_Paginate(object sender, PaginateEventArgs e)
{
previewPages.Clear(); // 打印預覽頁
printingRoot.Children.Clear(); // 實際發送到打印機的內容
RichTextBlockOverflow lastRichText;
PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);
PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);
// 添加第一個打印預覽頁,以及更新 printingRoot 中的內容
lastRichText = AddPreviewPageAndPrintPage(null, pageDescription);
// 添加之後的全部打印預覽頁,以及更新 printingRoot 中的內容
while (lastRichText.HasOverflowContent && lastRichText.Visibility == Visibility.Visible)
{
lastRichText = AddPreviewPageAndPrintPage(lastRichText, pageDescription);
}
// 設置打印頁數
printDocument.SetPreviewPageCount(previewPages.Count, PreviewPageCountType.Intermediate);
}
// 當系統請求將打印內容中的某一頁顯示在預覽窗口時
private void printDocument_GetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
// 指定當前的打印預覽頁
printDocument.SetPreviewPage(e.PageNumber, previewPages[e.PageNumber - 1]);
}
// 當系統請求將打印內容發送到打印機時
private void printDocument_AddPages(object sender, AddPagesEventArgs e)
{
for (int i = 0; i < previewPages.Count; i++)
{
// 添加到打印列表
printDocument.AddPage(previewPages[i]);
}
// 打印列表中的數據已經全部准備好了
printDocument.AddPagesComplete();
}
// 向 previewPages 添加一個預覽頁,以及向 printingRoot 添加一個打印內容,同時返回本頁所對應的下一頁的 RichTextBlockOverflow
private RichTextBlockOverflow AddPreviewPageAndPrintPage(RichTextBlockOverflow lastRichText, PrintPageDescription printPageDescription)
{
// 需要添加到 previewPages 的預覽頁
FrameworkElement previewPage;
// 添加到 previewPages 的打印頁所對應的下一頁的 RichTextBlockOverflow
RichTextBlockOverflow textOverflow;
if (lastRichText == null) // 第一頁
{
previewPage = printPage;
StackPanel footer = (StackPanel)previewPage.FindName("footer"); // 第一頁不顯示頁腳
footer.Visibility = Visibility.Collapsed;
}
else // 非第一頁
{
previewPage = new ContinuationPage(lastRichText);
}
// 打印頁的寬和高
previewPage.Width = printPageDescription.PageSize.Width;
previewPage.Height = printPageDescription.PageSize.Height;
// 打印頁的頁邊距
Grid printableArea = (Grid)previewPage.FindName("printableArea");
double applicationContentMarginLeft = 0.075; // 頁的左右邊距,即左右邊距加在一起占15% 的空間
double applicationContentMarginTop = 0.03; // 頁的上下邊距,即上下邊距加在一起占 6%的空間
double marginWidth = Math.Max(printPageDescription.PageSize.Width - printPageDescription.ImageableRect.Width, printPageDescription.PageSize.Width * applicationContentMarginLeft * 2);
double marginHeight = Math.Max(printPageDescription.PageSize.Height - printPageDescription.ImageableRect.Height, printPageDescription.PageSize.Height * applicationContentMarginTop * 2);
// 打印區域的寬和高
printableArea.Width = printPage.Width - marginWidth;
printableArea.Height = printPage.Height - marginHeight;
// 向 printingRoot 添加一個打印內容,以便發送到打印機打印
printingRoot.Children.Add(previewPage);
printingRoot.InvalidateMeasure();
printingRoot.UpdateLayout();
// 獲取本頁所對應的下一頁的 RichTextBlockOverflow
textOverflow = (RichTextBlockOverflow)previewPage.FindName("textOverflow");
if (!textOverflow.HasOverflowContent && textOverflow.Visibility ==
Visibility.Visible)
{
StackPanel footer = (StackPanel)previewPage.FindName("footer"); // 最後一頁才顯
示頁腳
footer.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
// 向 previewPages 添加新頁
previewPages.Add(previewPage);
return textOverflow;
}
}
}
OK
[源碼下載]:http://files.cnblogs.com/webabcd/Windows8.rar