WPF中打印问题的探讨[转]
轉自:http://blog.sina.com.cn/s/blog_624dc0120100ld6m.html
?
????最近在做一個WPF方面的項目,在打印功能實現上費了很大勁。因為我原來是在做Winform方面的項目,接受WPF時感覺還很相似,可仔細往里做下去卻發現兩者外看相似,實則差異很大,打印就是其中很大的差距。Winform有對應的對話框圍繞打印核心類PrintDocument進行操作,而WPF里則是在PrintDialog里進行擴展。WPF簡單的打印很簡單,幾行代碼就夠,可要實現較大功能時就需要很多的擴展,如分頁打印及對打印允許客戶有較大的設置自由度時,就很麻煩了。我以我這次的功能實現與大家進行探討。
????常見的打印方式有以下三中:
????第一種:對單一控件內容的打印。
????private void billtitle_btn_PrintClick(object sender, RoutedEventArgs e)
????????{
????????????PrintDialog printDialog = new PrintDialog();
????????????if (printDialog.ShowDialog() == true)
????????????{
????????????????printDialog.PrintVisual(Mainwindow, "123");
????????????}
????????}
?????其中Mainwindow是控件名,也可以是ListView等控件,只要把名稱傳入即可。很簡單,不過不實用,因為這種方法沒用自由度,是按系統默認進行打印且只能打印在一頁上,數據多了就不行。
?????第二種:根據PrintDialog進行功能擴展,就可以對打印功能在一定程度上擴展。??
| /// <summary> ??????//創建一個PrintDocument的實例 ??????//將事件處理函數添加到PrintDocument的PrintPage事件中 ??????//把PrintDialog的Document屬性設為上面配置好的PrintDocument的實例 ??????//根據用戶的選擇,開始打印 ???//設置打印機開始打印的事件處理函數 ????在這就可以看出Winform與WPF打印的不同了,在WPF在PrintDocument是一個打印方法。WPF有兩種打印途徑,一種是第一種方法中的PrintVisual,另一種就是PrintDocument。 ????第三種:具體步驟如下: 1.PrintDialog This sample illustrates how to create an instance of a simple PrintDialog and then display it. The sample uses both Extensible Application Markup Language (XAML) and procedural code. 這個示例演示了如何進行一個最簡單的打印工作,為此需要引入兩個dll:ReachFramework.dll和System.Printing。 InvokePrint方法只是顯示了一個PrintDialog打印框,并未進行打印工作: PrintDialog pDialog = new PrintDialog(); 有 PrintableAreaHeight和PrintableAreaWidth兩個屬性,分別用來表示可打印區域的高和寬。 而對 PrintDialog的設置,可以保存在PrintTicket中,下次再打開PrintDialog,就不必重復進行設置了。 PrintDialog pDialog = new PrintDialog(); 同樣,選擇使用哪一臺打印機的設置,存放在PrintQueue中,下次再打開PrintDialog,也不用再次設置了。 PrintDialog pDialog = new PrintDialog(); 如果要把特定的內容打印輸出,則需要調用PrintDialog的PrintVisual方法: if ((bool)pDialog.ShowDialog().GetValueOrDefault()) 我們能打印的,都是Visual類型的對象,其中UIElement派生于 Visual,從而我們可以打印所有Panel、控件和其它元素,最一般的方法是使用派生于Visual的DrawingVisual類,利用它的 RenderOpen方法生成DrawingContext對象,為其繪制圖形,最后使用PrintDialog的PrintVisual方法,輸出圖形 和文字。 注意到,pDialog.ShowDialog()返回的是可空類型?bool,為此需要使用 GetValueOrDefault將其轉為bool值,對于null值也會轉為false。 2.EnumerateSubsetOfPrintQueues EnumerateSubsetOfPrintQueues shows how to use the EnumeratedPrintQueueTypes enumeration to get a subset of available print queues. 這個程序演示了如何得到本地和共享的所有打印機列表。為此,需要 使用到EnumeratedPrintQueueTypes枚舉中的Local和Shared兩個值,組合成一個數組, EnumeratedPrintQueueTypes[] enumerationFlags = ??????????????????????{EnumeratedPrintQueueTypes.Local,EnumeratedPrintQueueTypes.Shared}; 作為參數傳遞到查詢方法GetPrintQueues中: LocalPrintServer printServer = new LocalPrintServer(); 接著就可 以對PrintQueueCollection進行遍歷了,獲取每一個的PrintQueue名稱和所在位置: foreach (PrintQueue printer in printQueuesOnLocalServer) ???下面就看我的方法了,先創建一個打印用的類:DataPaginator,它繼承了Document虛基類,并進行擴展,從而為我們的功能實現做鋪墊。 ??public class DataPaginator : DocumentPaginator ????????public override Size PageSize ????????#region??構造函數相關方法 |
?
????又構造函數可知,我們需傳入一個DataTable,這樣可打印的內容、樣式等就寬泛多了。DataTable可直接獲取,也可自己根據需要構建,我在項目時是根據顯示的數據構建一個DataTable。代碼如下:
????/// <summary>
????????/// 獲取要打印的數據
????????/// </summary>
????????private DataTable GetDataTable()
????????{
????????????DataTable table = new DataTable("Data Table");???????????
????????????// Declare variables for DataColumn and DataRow objects.
????????????DataColumn column;
????????????DataRow row;
????????????// Create new DataColumn, set DataType,
????????????// ColumnName and add to DataTable.???
????????????column = new DataColumn();
????????????column.DataType =Type.GetType("System.Int32");
????????????column.ColumnName = "id";
????????????column.Caption = "編號";
????????????column.ReadOnly = true;
????????????column.Unique = true;
????????????// Add the Column to the DataColumnCollection.
????????????table.Columns.Add(column);
????????????// Create second column.
????????????column = new DataColumn();
????????????column.DataType = Type.GetType("System.String");
????????????column.ColumnName = "Name";
????????????column.AutoIncrement = false;
????????????column.Caption = "姓名";
????????????column.ReadOnly = false;
????????????column.Unique = false;
????????????// Add the column to the table.
????????????table.Columns.Add(column);
????????????//Create third column
????????????column = new DataColumn();
????????????column.DataType = Type.GetType("System.String");
????????????column.ColumnName = "Age";
????????????column.AutoIncrement = false;
????????????column.Caption = "年齡";
????????????column.ReadOnly = false;
????????????column.Unique = false;
????????????// Add the column to the table.
????????????table.Columns.Add(column);
????????????//Create forth column
????????????column = new DataColumn();
????????????column.DataType = Type.GetType("System.String");
????????????column.ColumnName = "Pay";
????????????column.AutoIncrement = false;
????????????column.Caption = "工資";
????????????column.ReadOnly = false;
????????????column.Unique = false;
????????????// Add the column to the table.
????????????table.Columns.Add(column);
????????????// Make the ID column the primary key column.
????????????DataColumn[] PrimaryKeyColumns = new DataColumn[1];
????????????PrimaryKeyColumns[0] = table.Columns["id"];
????????????table.PrimaryKey = PrimaryKeyColumns;
????????????// Instantiate the DataSet variable.
????????????//dataSet = new DataSet();
????????????// Add the new DataTable to the DataSet.
????????????//dataSet.Tables.Add(table);
????????????// Create three new DataRow objects and add
????????????// them to the DataTable
????????????for (int i = 0; i <= 60; i++)
????????????{
????????????????row = table.NewRow();??????????????
????????????????row["id"] = i+1;
????????????????row["Name"] = "zhangsan " + (i+1).ToString();
????????????????row["Age"] = 20 + i;
????????????????row["Pay"] = 50 * (i + 1);
????????????????table.Rows.Add(row);
????????????}
????????????return table;
????????}
??????由此就可以開始打印了:
????private void BT_MultiPrint_Click(object sender, RoutedEventArgs e)
????????{
????????????PrintDialog printDialog = new PrintDialog();
????????????if (printDialog.ShowDialog() == true)
????????????{
????????????????DataTable dt = GetDataTable();
????????????????try
????????????????{
????????????????????DataPaginator dp = new DataPaginator(dt, new Typeface("SimSun"), 16, 96 * 0.75, new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight));
????????????????????printDialog.PrintDocument(dp, "Test Page");?????????????
????????????????}
????????????????catch
????????????????{
????????????????????MessageBox.Show("無法打印!");
????????????????}???????????????
????????????}????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
????????}
?????試用后效果還不錯。Winform里的打印功能比這強大的多,可以將其使用的控件擴展為WPF里的控件,或進行別的處理。在這就不論述,有興趣的可以自己去試試。
轉載于:https://www.cnblogs.com/weivyuan/archive/2013/01/08/2851411.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的WPF中打印问题的探讨[转]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu 3079水题
- 下一篇: 监测ASP.NET MVC 网站