mirror of
https://github.com/Stone-Red-Code/docs-desktop.git
synced 2026-09-07 16:06:07 +02:00
Printing in WPF port for .NET (#1156)
* Initial files * update toc * Content update - print-xps-files (user story 1861941) (#1151) * Add C# and VB sample code projects * Fix comments * Update C# and VB code * Add article * Further edits * Reviewer requested edits * Further edits * Use xref to link to API * Minor edits * Content update - invoke-print-dialog (user story 1861941) (#1141) * Content update including C# WPF project * Fix link * Remove test code * Further doc and C# sample edits * Add feature: printing with no print dialog * Separate out specific page range print functionality * Cleanup comments * UI tweaks * Add VB sample code project * Code file formatting * Update dotnet-desktop-guide/net/wpf/documents/how-to-display-print-dialog.md Co-authored-by: Andy (Steve) De George <[email protected]> * Add page range printing * Minor edits * Update dotnet-desktop-guide/net/wpf/documents/snippets/how-to-display-print-dialog/csharp/MainWindow.xaml.cs Co-authored-by: Andy (Steve) De George <[email protected]> * Update dotnet-desktop-guide/net/wpf/documents/how-to-display-print-dialog.md Co-authored-by: Andy (Steve) De George <[email protected]> * Promote example headings * Reorganize and add detail * Minor edits * Add detail * Further edits * Further edits * Add resource links * Add alternative API suggestions to a tip * Minor edit Co-authored-by: Andy (Steve) De George <[email protected]> * Content update - print-overview (user story 1861941) (#1153) * Add C# and VB sample code projects * Add article * Add redirects Co-authored-by: Tris Shores <[email protected]>
This commit is contained in:
co-authored by
Tris Shores
parent
e96218f17e
commit
bdd178c010
+9
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="CodeSampleCsharp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:CodeSampleCsharp"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace CodeSampleCsharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<Window x:Class="CodeSampleCsharp.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="Print an XPS file" Height="149" Width="509">
|
||||
<Grid Margin="0,0,0,10">
|
||||
<Label Content="Select XPS file" HorizontalAlignment="Left" Margin="27,12,0,0" VerticalAlignment="Top" FontSize="11" Height="25" Width="78"/>
|
||||
|
||||
<Button Content="Browse" HorizontalAlignment="Left" Margin="428,35,0,0" VerticalAlignment="Top" Width="48" x:Name="btnBrowse" Height="20"/>
|
||||
<TextBox HorizontalAlignment="Left" Margin="32,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="391" FontSize="14" x:Name="txtXpsFilePath" Height="21"/>
|
||||
<Button Content="Print" HorizontalAlignment="Left" Margin="32,71,0,0" FontSize="14" Width="51" x:Name="btnPrint" Height="28" VerticalAlignment="Top"/>
|
||||
<CheckBox x:Name="cbxHidePrintDialog" Content="Hide print dialog" HorizontalAlignment="Left" Margin="124,77,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.376,-0.054"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Xps.Packaging;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace CodeSampleCsharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml.
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// Events.
|
||||
btnBrowse.Click += BtnBrowse_Click;
|
||||
btnPrint.Click += BtnPrint_Click;
|
||||
}
|
||||
|
||||
private void BtnBrowse_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Configure an open file dialog box.
|
||||
OpenFileDialog openFileDialog = new()
|
||||
{
|
||||
FileName = "Document",
|
||||
DefaultExt = ".xps",
|
||||
Filter = "Text documents (.xps)|*.xps"
|
||||
};
|
||||
|
||||
// Show open file dialog box.
|
||||
bool? result = openFileDialog.ShowDialog();
|
||||
|
||||
// Process open file dialog box results.
|
||||
if (result == true)
|
||||
{
|
||||
// Show selected XPS file path.
|
||||
txtXpsFilePath.Text = openFileDialog.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnPrint_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Check the file exists.
|
||||
if (!File.Exists(txtXpsFilePath.Text))
|
||||
{
|
||||
MessageBox.Show("First select an XPS file.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the print dialog visibility.
|
||||
bool hidePrintDialog = cbxHidePrintDialog.IsChecked == true;
|
||||
|
||||
// Print whole document.
|
||||
bool isPrinted = PrintWholeDocument(txtXpsFilePath.Text, hidePrintDialog);
|
||||
MessageBox.Show($"PrintWholeDocument {(isPrinted ? "printed" : "failed to print")}.");
|
||||
|
||||
// Print a specific range of document pages as specified in the print dialog.
|
||||
if (!hidePrintDialog)
|
||||
{
|
||||
isPrinted = PrintDocumentPageRange(txtXpsFilePath.Text);
|
||||
MessageBox.Show($"PrintDocumentPageRange {(isPrinted ? "printed" : "failed to print")}.");
|
||||
}
|
||||
}
|
||||
|
||||
// <SampleCode1>
|
||||
/// <summary>
|
||||
/// Print all pages of an XPS document.
|
||||
/// Optionally, hide the print dialog window.
|
||||
/// </summary>
|
||||
/// <param name="xpsFilePath">Path to source XPS file</param>
|
||||
/// <param name="hidePrintDialog">Whether to hide the print dialog window (shown by default)</param>
|
||||
/// <returns>Whether the document printed</returns>
|
||||
public static bool PrintWholeDocument(string xpsFilePath, bool hidePrintDialog = false)
|
||||
{
|
||||
// Create the print dialog object and set options.
|
||||
PrintDialog printDialog = new();
|
||||
|
||||
if (!hidePrintDialog)
|
||||
{
|
||||
// Display the dialog. This returns true if the user presses the Print button.
|
||||
bool? isPrinted = printDialog.ShowDialog();
|
||||
if (isPrinted != true)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Print the whole document.
|
||||
try
|
||||
{
|
||||
// Open the selected document.
|
||||
XpsDocument xpsDocument = new(xpsFilePath, FileAccess.Read);
|
||||
|
||||
// Get a fixed document sequence for the selected document.
|
||||
FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();
|
||||
|
||||
// Create a paginator for all pages in the selected document.
|
||||
DocumentPaginator docPaginator = fixedDocSeq.DocumentPaginator;
|
||||
|
||||
// Print to a new file.
|
||||
printDialog.PrintDocument(docPaginator, $"Printing {Path.GetFileName(xpsFilePath)}");
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.Message);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// </SampleCode1>
|
||||
|
||||
// <SampleCode2>
|
||||
/// <summary>
|
||||
/// Print a specific range of pages within an XPS document.
|
||||
/// </summary>
|
||||
/// <param name="xpsFilePath">Path to source XPS file</param>
|
||||
/// <returns>Whether the document printed</returns>
|
||||
public static bool PrintDocumentPageRange(string xpsFilePath)
|
||||
{
|
||||
// Create the print dialog object and set options.
|
||||
PrintDialog printDialog = new()
|
||||
{
|
||||
UserPageRangeEnabled = true
|
||||
};
|
||||
|
||||
// Display the dialog. This returns true if the user presses the Print button.
|
||||
bool? isPrinted = printDialog.ShowDialog();
|
||||
if (isPrinted != true)
|
||||
return false;
|
||||
|
||||
// Print a specific page range within the document.
|
||||
try
|
||||
{
|
||||
// Open the selected document.
|
||||
XpsDocument xpsDocument = new(xpsFilePath, FileAccess.Read);
|
||||
|
||||
// Get a fixed document sequence for the selected document.
|
||||
FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();
|
||||
|
||||
// Create a paginator for all pages in the selected document.
|
||||
DocumentPaginator docPaginator = fixedDocSeq.DocumentPaginator;
|
||||
|
||||
// Check whether a page range was specified in the print dialog.
|
||||
if (printDialog.PageRangeSelection == PageRangeSelection.UserPages)
|
||||
{
|
||||
// Create a document paginator for the specified range of pages.
|
||||
docPaginator = new DocPaginator(fixedDocSeq.DocumentPaginator, printDialog.PageRange);
|
||||
}
|
||||
|
||||
// Print to a new file.
|
||||
printDialog.PrintDocument(docPaginator, $"Printing {Path.GetFileName(xpsFilePath)}");
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.Message);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extend the abstract DocumentPaginator class to support page range printing. This class is based on the following online resources:
|
||||
///
|
||||
/// https://www.thomasclaudiushuber.com/2009/11/24/wpf-printing-how-to-print-a-pagerange-with-wpfs-printdialog-that-means-the-user-can-select-specific-pages-and-only-these-pages-are-printed/
|
||||
///
|
||||
/// https://social.msdn.microsoft.com/Forums/vstudio/en-US/9180e260-0791-4f2d-962d-abcb22ba8d09/how-to-print-multiple-page-ranges-with-wpf-printdialog
|
||||
///
|
||||
/// https://social.msdn.microsoft.com/Forums/en-US/841e804b-9130-4476-8709-0d2854c11582/exception-quotfixedpage-cannot-contain-another-fixedpagequot-when-printing-to-the-xps-document?forum=wpf
|
||||
/// </summary>
|
||||
public class DocPaginator : DocumentPaginator
|
||||
{
|
||||
private readonly DocumentPaginator _documentPaginator;
|
||||
private readonly int _startPageIndex;
|
||||
private readonly int _endPageIndex;
|
||||
private readonly int _pageCount;
|
||||
|
||||
public DocPaginator(DocumentPaginator documentPaginator, PageRange pageRange)
|
||||
{
|
||||
// Set document paginator.
|
||||
_documentPaginator = documentPaginator;
|
||||
|
||||
// Set page indices.
|
||||
_startPageIndex = pageRange.PageFrom - 1;
|
||||
_endPageIndex = pageRange.PageTo - 1;
|
||||
|
||||
// Validate and set page count.
|
||||
if (_startPageIndex >= 0 &&
|
||||
_endPageIndex >= 0 &&
|
||||
_startPageIndex <= _documentPaginator.PageCount - 1 &&
|
||||
_endPageIndex <= _documentPaginator.PageCount - 1 &&
|
||||
_startPageIndex <= _endPageIndex)
|
||||
_pageCount = _endPageIndex - _startPageIndex + 1;
|
||||
}
|
||||
|
||||
public override bool IsPageCountValid => true;
|
||||
|
||||
public override int PageCount => _pageCount;
|
||||
|
||||
public override IDocumentPaginatorSource Source => _documentPaginator.Source;
|
||||
|
||||
public override Size PageSize { get => _documentPaginator.PageSize; set => _documentPaginator.PageSize = value; }
|
||||
|
||||
public override DocumentPage GetPage(int pageNumber)
|
||||
{
|
||||
DocumentPage documentPage = _documentPaginator.GetPage(_startPageIndex + pageNumber);
|
||||
|
||||
// Workaround for "FixedPageInPage" exception.
|
||||
if (documentPage.Visual is FixedPage fixedPage)
|
||||
{
|
||||
var containerVisual = new ContainerVisual();
|
||||
foreach (object child in fixedPage.Children)
|
||||
{
|
||||
var childClone = (UIElement)child.GetType().GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(child, null);
|
||||
|
||||
FieldInfo parentField = childClone.GetType().GetField("_parent", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (parentField != null)
|
||||
{
|
||||
parentField.SetValue(childClone, null);
|
||||
containerVisual.Children.Add(childClone);
|
||||
}
|
||||
}
|
||||
|
||||
return new DocumentPage(containerVisual, documentPage.Size, documentPage.BleedBox, documentPage.ContentBox);
|
||||
}
|
||||
|
||||
return documentPage;
|
||||
}
|
||||
}
|
||||
// </SampleCode2>
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="Application"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:CodeSampleVb"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
Class Application
|
||||
|
||||
' Application-level events, such as Startup, Exit, and DispatcherUnhandledException
|
||||
' can be handled in this file.
|
||||
|
||||
End Class
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
Imports System.Windows
|
||||
|
||||
'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found.
|
||||
'1st parameter: where theme specific resource dictionaries are located
|
||||
'(used if a resource is not found in the page,
|
||||
' or application resource dictionaries)
|
||||
|
||||
'2nd parameter: where the generic resource dictionary is located
|
||||
'(used if a resource is not found in the page,
|
||||
'app, and any theme specific resource dictionaries)
|
||||
<Assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<RootNamespace>CodeSampleVb</RootNamespace>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Import Include="System.Windows" />
|
||||
<Import Include="System.Windows.Controls" />
|
||||
<Import Include="System.Windows.Data" />
|
||||
<Import Include="System.Windows.Documents" />
|
||||
<Import Include="System.Windows.Input" />
|
||||
<Import Include="System.Windows.Media" />
|
||||
<Import Include="System.Windows.Media.Imaging" />
|
||||
<Import Include="System.Windows.Navigation" />
|
||||
<Import Include="System.Windows.Shapes" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<Window x:Class="CodeSampleVb.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="Print an XPS file" Height="149" Width="509">
|
||||
<Grid Margin="0,0,0,10">
|
||||
<Label Content="Select XPS file" HorizontalAlignment="Left" Margin="27,12,0,0" VerticalAlignment="Top" FontSize="11" Height="25" Width="78"/>
|
||||
|
||||
<Button Content="Browse" HorizontalAlignment="Left" Margin="428,35,0,0" VerticalAlignment="Top" Width="48" x:Name="btnBrowse" Height="20"/>
|
||||
<TextBox HorizontalAlignment="Left" Margin="32,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="391" FontSize="14" x:Name="txtXpsFilePath" Height="21"/>
|
||||
<Button Content="Print" HorizontalAlignment="Left" Margin="32,71,0,0" FontSize="14" Width="51" x:Name="btnPrint" Height="28" VerticalAlignment="Top"/>
|
||||
<CheckBox x:Name="cbxHidePrintDialog" Content="Hide print dialog" HorizontalAlignment="Left" Margin="124,77,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.376,-0.054"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
Imports System
|
||||
Imports System.IO
|
||||
Imports System.Reflection
|
||||
Imports System.Windows.Xps.Packaging
|
||||
Imports Microsoft.Win32
|
||||
|
||||
Namespace CodeSampleVb
|
||||
Partial Public Class MainWindow
|
||||
Inherits Window
|
||||
|
||||
''' <summary>
|
||||
''' Interaction logic for MainWindow.xaml
|
||||
''' </summary>
|
||||
Public Sub New()
|
||||
|
||||
InitializeComponent()
|
||||
|
||||
' Events.
|
||||
AddHandler btnBrowse.Click, AddressOf BtnBrowse_Click
|
||||
AddHandler btnPrint.Click, AddressOf BtnPrint_Click
|
||||
|
||||
End Sub
|
||||
|
||||
|
||||
Private Sub BtnBrowse_Click(sender As Object, e As RoutedEventArgs)
|
||||
|
||||
' Configure an open file dialog box.
|
||||
Dim openFileDialog As New OpenFileDialog With {
|
||||
.FileName = "Document",
|
||||
.DefaultExt = ".xps",
|
||||
.Filter = "Text documents (.xps)|*.xps"
|
||||
}
|
||||
|
||||
' Show open file dialog box.
|
||||
Dim result As Boolean? = openFileDialog.ShowDialog()
|
||||
|
||||
' Process open file dialog box results.
|
||||
If result = True Then
|
||||
' Show selected XPS file path.
|
||||
txtXpsFilePath.Text = openFileDialog.FileName
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub BtnPrint_Click(sender As Object, e As RoutedEventArgs)
|
||||
|
||||
' Check the file exists.
|
||||
If Not File.Exists(txtXpsFilePath.Text) Then
|
||||
MessageBox.Show("First select an XPS file.")
|
||||
Return
|
||||
End If
|
||||
|
||||
' Get the print dialog visibility.
|
||||
Dim hidePrintDialog = cbxHidePrintDialog.IsChecked = True
|
||||
Dim isPrinted As Boolean
|
||||
|
||||
' Print whole document.
|
||||
isPrinted = PrintWholeDocument(txtXpsFilePath.Text, hidePrintDialog)
|
||||
MessageBox.Show($"PrintWholeDocument {If(isPrinted, "printed", "failed to print")}.")
|
||||
|
||||
' Print a specific range of document pages as specified in the print dialog.
|
||||
If Not hidePrintDialog Then
|
||||
|
||||
isPrinted = PrintDocumentPageRange(txtXpsFilePath.Text)
|
||||
MessageBox.Show($"PrintDocumentPageRange {If(isPrinted, "printed", "failed to print")}.")
|
||||
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
' <SampleCode1>
|
||||
''' <summary>
|
||||
''' Print all pages of an XPS document.
|
||||
''' Optionally, print all pages without showing a print dialog window.
|
||||
''' </summary>
|
||||
''' <param name="xpsFilePath">Path to source XPS file</param>
|
||||
''' <param name="hidePrintDialog">Whether to hide the print dialog window (shown by default)</param>
|
||||
''' <returns>Whether the document printed</returns>
|
||||
Public Shared Function PrintWholeDocument(xpsFilePath As String, Optional hidePrintDialog As Boolean = False) As Boolean
|
||||
|
||||
' Create the print dialog object and set options.
|
||||
Dim printDialog As New PrintDialog
|
||||
|
||||
If Not hidePrintDialog Then
|
||||
|
||||
' Display the dialog. This returns true if the user presses the Print button.
|
||||
Dim isPrinted As Boolean? = printDialog.ShowDialog()
|
||||
If isPrinted <> True Then Return False
|
||||
|
||||
End If
|
||||
|
||||
' Print the whole document.
|
||||
Try
|
||||
|
||||
' Open the selected document.
|
||||
Dim xpsDocument As New XpsDocument(xpsFilePath, FileAccess.Read)
|
||||
|
||||
' Get a fixed document sequence for the selected document.
|
||||
Dim fixedDocSeq As FixedDocumentSequence = xpsDocument.GetFixedDocumentSequence()
|
||||
|
||||
' Create a paginator for all pages in the selected document.
|
||||
Dim docPaginator As DocumentPaginator = fixedDocSeq.DocumentPaginator
|
||||
|
||||
' Print to a new file.
|
||||
printDialog.PrintDocument(docPaginator, $"Printing {Path.GetFileName(xpsFilePath)}")
|
||||
|
||||
Return True
|
||||
|
||||
Catch e As Exception
|
||||
|
||||
MessageBox.Show(e.Message)
|
||||
|
||||
Return False
|
||||
|
||||
End Try
|
||||
|
||||
End Function
|
||||
' </SampleCode1>
|
||||
|
||||
' <SampleCode2>
|
||||
''' <summary>
|
||||
''' Print a specific range of pages within an XPS document.
|
||||
''' </summary>
|
||||
''' <param name="xpsFilePath">Path to source XPS file</param>
|
||||
''' <returns>Whether the document printed</returns>
|
||||
Public Shared Function PrintDocumentPageRange(xpsFilePath As String) As Boolean
|
||||
|
||||
' Create the print dialog object and set options.
|
||||
Dim printDialog As New PrintDialog With {
|
||||
.UserPageRangeEnabled = True
|
||||
}
|
||||
|
||||
' Display the dialog. This returns true if the user presses the Print button.
|
||||
Dim isPrinted As Boolean? = printDialog.ShowDialog()
|
||||
If isPrinted <> True Then Return False
|
||||
|
||||
' Print a specific page range within the document.
|
||||
Try
|
||||
|
||||
' Open the selected document.
|
||||
Dim xpsDocument As New XpsDocument(xpsFilePath, FileAccess.Read)
|
||||
|
||||
' Get a fixed document sequence for the selected document.
|
||||
Dim fixedDocSeq As FixedDocumentSequence = xpsDocument.GetFixedDocumentSequence()
|
||||
|
||||
' Create a paginator for all pages in the selected document.
|
||||
Dim docPaginator As DocumentPaginator = fixedDocSeq.DocumentPaginator
|
||||
|
||||
' Check whether a page range was specified in the print dialog.
|
||||
If printDialog.PageRangeSelection = PageRangeSelection.UserPages Then
|
||||
|
||||
' Create a document paginator for the specified range of pages.
|
||||
docPaginator = New DocPaginator(fixedDocSeq.DocumentPaginator, printDialog.PageRange)
|
||||
|
||||
End If
|
||||
|
||||
' Print to a new file.
|
||||
printDialog.PrintDocument(docPaginator, $"Printing {Path.GetFileName(xpsFilePath)}")
|
||||
|
||||
Return True
|
||||
|
||||
Catch e As Exception
|
||||
|
||||
MessageBox.Show(e.Message)
|
||||
|
||||
Return False
|
||||
|
||||
End Try
|
||||
|
||||
End Function
|
||||
|
||||
' <summary>
|
||||
' Extend the abstract DocumentPaginator class to support page range printing.
|
||||
' This class is based on the following online resources:
|
||||
' https://www.thomasclaudiushuber.com/2009/11/24/wpf-printing-how-to-print-a-pagerange-with-wpfs-printdialog-
|
||||
' that-means-the-user-can-select-specific-pages-and-only-these-pages-are-printed/
|
||||
' https://social.msdn.microsoft.com/Forums/vstudio/en-US/9180e260-0791-4f2d-962d-abcb22ba8d09/how-to-print-
|
||||
' multiple-page-ranges-with-wpf-printdialog
|
||||
' https://social.msdn.microsoft.com/Forums/en-US/841e804b-9130-4476-8709-0d2854c11582/exception-quotfixedpage-
|
||||
' cannot-contain-another-fixedpagequot-when-printing-to-the-xps-document?forum=wpf
|
||||
' </summary>
|
||||
Public Class DocPaginator
|
||||
Inherits DocumentPaginator
|
||||
|
||||
Private ReadOnly _documentPaginator As DocumentPaginator
|
||||
Private ReadOnly _startPageIndex As Integer
|
||||
Private ReadOnly _endPageIndex As Integer
|
||||
Private ReadOnly _pageCount As Integer
|
||||
|
||||
Public Sub New(documentPaginator As DocumentPaginator, pageRange As PageRange)
|
||||
|
||||
' Set document paginator.
|
||||
_documentPaginator = documentPaginator
|
||||
|
||||
' Set page indices.
|
||||
_startPageIndex = pageRange.PageFrom - 1
|
||||
_endPageIndex = pageRange.PageTo - 1
|
||||
|
||||
' Validate And set page count.
|
||||
If _startPageIndex >= 0 AndAlso
|
||||
_endPageIndex >= 0 AndAlso
|
||||
_startPageIndex <= _documentPaginator.PageCount - 1 AndAlso
|
||||
_endPageIndex <= _documentPaginator.PageCount - 1 AndAlso
|
||||
_startPageIndex <= _endPageIndex Then
|
||||
_pageCount = _endPageIndex - _startPageIndex + 1
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
Public Overrides ReadOnly Property IsPageCountValid As Boolean
|
||||
Get
|
||||
Return True
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public Overrides ReadOnly Property PageCount As Integer
|
||||
Get
|
||||
Return _pageCount
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public Overrides ReadOnly Property Source As IDocumentPaginatorSource
|
||||
Get
|
||||
Return _documentPaginator.Source
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public Overrides Property PageSize As Size
|
||||
Get
|
||||
Return _documentPaginator.PageSize
|
||||
End Get
|
||||
Set(value As Size)
|
||||
_documentPaginator.PageSize = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Public Overrides Function GetPage(pageNumber As Integer) As DocumentPage
|
||||
|
||||
Dim documentPage As DocumentPage = _documentPaginator.GetPage(_startPageIndex + pageNumber)
|
||||
|
||||
' Workaround for "FixedPageInPage" exception.
|
||||
If documentPage.Visual.GetType() Is GetType(FixedPage) Then
|
||||
|
||||
Dim fixedPage As FixedPage = documentPage.Visual
|
||||
Dim containerVisual = New ContainerVisual()
|
||||
|
||||
For Each child As Object In fixedPage.Children
|
||||
Dim childClone = CType(child.[GetType]().GetMethod("MemberwiseClone", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(child, Nothing), UIElement)
|
||||
Dim parentField As FieldInfo = childClone.[GetType]().GetField("_parent", BindingFlags.Instance Or BindingFlags.NonPublic)
|
||||
|
||||
If parentField IsNot Nothing Then
|
||||
parentField.SetValue(childClone, Nothing)
|
||||
containerVisual.Children.Add(childClone)
|
||||
End If
|
||||
Next
|
||||
|
||||
Return New DocumentPage(containerVisual, documentPage.Size, documentPage.BleedBox, documentPage.ContentBox)
|
||||
|
||||
End If
|
||||
|
||||
Return documentPage
|
||||
|
||||
End Function
|
||||
|
||||
End Class
|
||||
' </SampleCode2>
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="CodeSampleCsharp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:CodeSampleCsharp"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace CodeSampleCsharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<Window x:Class="CodeSampleCsharp.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="Print an XPS file" Height="149" Width="509">
|
||||
<Grid Margin="0,0,0,10">
|
||||
<Label Content="Enter the path to a folder that contains XPS files" HorizontalAlignment="Left" Margin="27,12,0,0" VerticalAlignment="Top" FontSize="11" Height="25" Width="339"/>
|
||||
<TextBox HorizontalAlignment="Left" Margin="32,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="447" FontSize="14" x:Name="txtFolderPath" Height="21"/>
|
||||
<Button Content="Print" HorizontalAlignment="Left" Margin="32,71,0,0" FontSize="14" Width="51" x:Name="btnPrint" Height="28" VerticalAlignment="Top" Click="BtnPrint_Click"/>
|
||||
<CheckBox x:Name="cbxValidateXps" Content="Validate XPS files" HorizontalAlignment="Left" Margin="137,78,0,0" VerticalAlignment="Top" IsChecked="True"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Printing;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace CodeSampleCsharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml.
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private async void BtnPrint_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Check that the folder exists.
|
||||
if (!Directory.Exists(txtFolderPath.Text))
|
||||
{
|
||||
MessageBox.Show("First select a valid folder path.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether any XPS files exist in the folder.
|
||||
string[] xpsFilePaths = Directory.GetFiles(path: txtFolderPath.Text, searchPattern: "*.xps");
|
||||
if (xpsFilePaths.Length == 0)
|
||||
{
|
||||
MessageBox.Show("No XPS files found.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine whether XPS validation is needed.
|
||||
bool fastCopy = cbxValidateXps.IsChecked == false;
|
||||
|
||||
// Batch add a collection of XPS files to the print queue.
|
||||
// Run asynchronously to avoid blocking the UI thread.
|
||||
bool isAllPrinted = await BatchAddToPrintQueueAsync(xpsFilePaths, fastCopy);
|
||||
|
||||
// Show result message.
|
||||
MessageBox.Show($"{(isAllPrinted ? "Added" : "Failed to add")} all documents to the print queue.");
|
||||
}
|
||||
|
||||
// <SampleCode1>
|
||||
/// <summary>
|
||||
/// Asyncronously, add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
|
||||
/// Handle the thread apartment state required by the PrintQueue.AddJob method.
|
||||
/// </summary>
|
||||
/// <param name="xpsFilePaths">A collection of XPS documents.</param>
|
||||
/// <param name="fastCopy">Whether to validate the XPS documents.</param>
|
||||
/// <returns>Whether all documents were added to the print queue.</returns>
|
||||
public static async Task<bool> BatchAddToPrintQueueAsync(IEnumerable<string> xpsFilePaths, bool fastCopy = false)
|
||||
{
|
||||
bool allAdded = true;
|
||||
|
||||
// Queue some work to run on the ThreadPool.
|
||||
// Wait for completion without blocking the calling thread.
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (fastCopy)
|
||||
allAdded = BatchAddToPrintQueue(xpsFilePaths, fastCopy);
|
||||
else
|
||||
{
|
||||
// Create a thread to call the PrintQueue.AddJob method.
|
||||
Thread newThread = new(() =>
|
||||
{
|
||||
allAdded = BatchAddToPrintQueue(xpsFilePaths, fastCopy);
|
||||
});
|
||||
|
||||
// Set the thread to single-threaded apartment state.
|
||||
newThread.SetApartmentState(ApartmentState.STA);
|
||||
|
||||
// Start the thread.
|
||||
newThread.Start();
|
||||
|
||||
// Wait for thread completion. Blocks the calling thread,
|
||||
// which is a ThreadPool thread.
|
||||
newThread.Join();
|
||||
}
|
||||
});
|
||||
|
||||
return allAdded;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
|
||||
/// </summary>
|
||||
/// <param name="xpsFilePaths">A collection of XPS documents.</param>
|
||||
/// <param name="fastCopy">Whether to validate the XPS documents.</param>
|
||||
/// <returns>Whether all documents were added to the print queue.</returns>
|
||||
public static bool BatchAddToPrintQueue(IEnumerable<string> xpsFilePaths, bool fastCopy)
|
||||
{
|
||||
bool allAdded = true;
|
||||
|
||||
// To print without getting the "Save Output File As" dialog, ensure
|
||||
// that your default printer is not the Microsoft XPS Document Writer,
|
||||
// Microsoft Print to PDF, or other print-to-file option.
|
||||
|
||||
// Get a reference to the default print queue.
|
||||
PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
|
||||
|
||||
// Iterate through the document collection.
|
||||
foreach (string xpsFilePath in xpsFilePaths)
|
||||
{
|
||||
// Get document name.
|
||||
string xpsFileName = Path.GetFileName(xpsFilePath);
|
||||
|
||||
try
|
||||
{
|
||||
// The AddJob method adds a new print job for an XPS
|
||||
// document into the print queue, and assigns a job name.
|
||||
// Use fastCopy to skip XPS validation and progress notifications.
|
||||
// If fastCopy is false, the thread that calls PrintQueue.AddJob
|
||||
// must have a single-threaded apartment state.
|
||||
PrintSystemJobInfo xpsPrintJob =
|
||||
defaultPrintQueue.AddJob(jobName: xpsFileName, documentPath: xpsFilePath, fastCopy);
|
||||
|
||||
// If the queue is not paused and the printer is working, then jobs will automatically begin printing.
|
||||
Debug.WriteLine($"Added {xpsFileName} to the print queue.");
|
||||
}
|
||||
catch (PrintJobException e)
|
||||
{
|
||||
allAdded = false;
|
||||
Debug.WriteLine($"Failed to add {xpsFileName} to the print queue: {e.Message}\r\n{e.InnerException}");
|
||||
}
|
||||
}
|
||||
|
||||
return allAdded;
|
||||
}
|
||||
// </SampleCode1>
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="Application"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:CodeSampleVb"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
Class Application
|
||||
|
||||
' Application-level events, such as Startup, Exit, and DispatcherUnhandledException
|
||||
' can be handled in this file.
|
||||
|
||||
End Class
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
Imports System.Windows
|
||||
|
||||
'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found.
|
||||
'1st parameter: where theme specific resource dictionaries are located
|
||||
'(used if a resource is not found in the page,
|
||||
' or application resource dictionaries)
|
||||
|
||||
'2nd parameter: where the generic resource dictionary is located
|
||||
'(used if a resource is not found in the page,
|
||||
'app, and any theme specific resource dictionaries)
|
||||
<Assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<RootNamespace>CodeSampleVb</RootNamespace>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Import Include="System.Windows" />
|
||||
<Import Include="System.Windows.Controls" />
|
||||
<Import Include="System.Windows.Data" />
|
||||
<Import Include="System.Windows.Documents" />
|
||||
<Import Include="System.Windows.Input" />
|
||||
<Import Include="System.Windows.Media" />
|
||||
<Import Include="System.Windows.Media.Imaging" />
|
||||
<Import Include="System.Windows.Navigation" />
|
||||
<Import Include="System.Windows.Shapes" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<Window x:Class="CodeSampleVb.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="Print an XPS file" Height="149" Width="509">
|
||||
<Grid Margin="0,0,0,10">
|
||||
<Label Content="Enter the path to a folder that contains XPS files" HorizontalAlignment="Left" Margin="27,12,0,0" VerticalAlignment="Top" FontSize="11" Height="25" Width="339"/>
|
||||
<TextBox HorizontalAlignment="Left" Margin="32,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="447" FontSize="14" x:Name="txtFolderPath" Height="21"/>
|
||||
<Button Content="Print" HorizontalAlignment="Left" Margin="32,71,0,0" FontSize="14" Width="51" x:Name="btnPrint" Height="28" VerticalAlignment="Top" Click="BtnPrint_Click"/>
|
||||
<CheckBox x:Name="cbxValidateXps" Content="Validate XPS files" HorizontalAlignment="Left" Margin="137,78,0,0" VerticalAlignment="Top" IsChecked="True"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
Imports System.IO
|
||||
Imports System.Printing
|
||||
Imports System.Threading
|
||||
|
||||
Namespace CodeSampleVb
|
||||
Partial Public Class MainWindow
|
||||
Inherits Window
|
||||
|
||||
''' <summary>
|
||||
''' Interaction logic for MainWindow.xaml
|
||||
''' </summary>
|
||||
Public Sub New()
|
||||
|
||||
InitializeComponent()
|
||||
|
||||
End Sub
|
||||
|
||||
Private Async Sub BtnPrint_Click(sender As Object, e As RoutedEventArgs)
|
||||
|
||||
' Check that the folder exists.
|
||||
If Not Directory.Exists(txtFolderPath.Text) Then
|
||||
MessageBox.Show("First select a valid folder path.")
|
||||
Return
|
||||
End If
|
||||
|
||||
' Check whether any XPS files exist in the folder.
|
||||
Dim xpsFilePaths = Directory.GetFiles(path:=txtFolderPath.Text, searchPattern:="*.xps")
|
||||
If xpsFilePaths.Length = 0 Then
|
||||
MessageBox.Show("No XPS files found.")
|
||||
Return
|
||||
End If
|
||||
|
||||
' Determine whether XPS validation is needed.
|
||||
Dim fastCopy As Boolean = cbxValidateXps.IsChecked = False
|
||||
|
||||
' Batch add a collection of XPS files to the print queue.
|
||||
' Run asynchronously to avoid blocking the UI thread.
|
||||
Dim isAllPrinted As Boolean = Await BatchAddToPrintQueueAsync(xpsFilePaths, fastCopy)
|
||||
|
||||
' Show result message.
|
||||
MessageBox.Show($"{If(isAllPrinted, "Added", "Failed to add")} all documents to the print queue.")
|
||||
|
||||
End Sub
|
||||
|
||||
' <SampleCode1>
|
||||
''' <summary>
|
||||
''' Asyncronously, add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
|
||||
''' Handle the thread apartment state required by the PrintQueue.AddJob method.
|
||||
''' </summary>
|
||||
''' <param name="xpsFilePaths">A collection of XPS documents.</param>
|
||||
''' <param name="fastCopy">Whether to validate the XPS documents.</param>
|
||||
''' <returns>Whether all documents were added to the print queue.</returns>
|
||||
Public Shared Async Function BatchAddToPrintQueueAsync(xpsFilePaths As IEnumerable(Of String), Optional fastCopy As Boolean = False) As Task(Of Boolean)
|
||||
|
||||
Dim isAllPrinted As Boolean = True
|
||||
|
||||
' Queue some work to run on the ThreadPool.
|
||||
' Wait for completion without blocking the calling thread.
|
||||
Await Task.Run(
|
||||
Sub()
|
||||
If fastCopy Then
|
||||
isAllPrinted = BatchAddToPrintQueue(xpsFilePaths, fastCopy)
|
||||
Else
|
||||
' Create a thread to call the PrintQueue.AddJob method.
|
||||
Dim newThread As New Thread(
|
||||
Sub()
|
||||
isAllPrinted = BatchAddToPrintQueue(xpsFilePaths, fastCopy)
|
||||
End Sub
|
||||
)
|
||||
|
||||
' Set the thread to single-threaded apartment state.
|
||||
newThread.SetApartmentState(ApartmentState.STA)
|
||||
|
||||
' Start the thread.
|
||||
newThread.Start()
|
||||
|
||||
' Wait for thread completion. Blocks the calling thread,
|
||||
' which is a ThreadPool thread.
|
||||
newThread.Join()
|
||||
End If
|
||||
End Sub
|
||||
)
|
||||
|
||||
Return isAllPrinted
|
||||
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Add a batch of XPS documents to the print queue using a PrintQueue.AddJob method.
|
||||
''' </summary>
|
||||
''' <param name="xpsFilePaths">A collection of XPS documents.</param>
|
||||
''' <param name="fastCopy">Whether to validate the XPS documents.</param>
|
||||
''' <returns>Whether all documents were added to the print queue.</returns>
|
||||
Public Shared Function BatchAddToPrintQueue(xpsFilePaths As IEnumerable(Of String), fastCopy As Boolean) As Boolean
|
||||
|
||||
Dim isAllPrinted As Boolean = True
|
||||
|
||||
' To print without getting the "Save Output File As" dialog, ensure
|
||||
' that your default printer is not the Microsoft XPS Document Writer,
|
||||
' Microsoft Print to PDF, or other print-to-file option.
|
||||
|
||||
' Get a reference to the default print queue.
|
||||
Dim defaultPrintQueue As PrintQueue = LocalPrintServer.GetDefaultPrintQueue()
|
||||
|
||||
' Iterate through the document collection.
|
||||
For Each xpsFilePath As String In xpsFilePaths
|
||||
|
||||
' Get document name.
|
||||
Dim xpsFileName As String = Path.GetFileName(xpsFilePath)
|
||||
|
||||
Try
|
||||
' The AddJob method adds a new print job for an XPS
|
||||
' document into the print queue, and assigns a job name.
|
||||
' Use fastCopy to skip XPS validation and progress notifications.
|
||||
' If fastCopy is false, the thread that calls PrintQueue.AddJob
|
||||
' must have a single-threaded apartment state.
|
||||
Dim xpsPrintJob As PrintSystemJobInfo = defaultPrintQueue.AddJob(jobName:=xpsFileName, documentPath:=xpsFilePath, fastCopy)
|
||||
|
||||
' If the queue is not paused and the printer is working, then jobs will automatically begin printing.
|
||||
Debug.WriteLine($"Added {xpsFileName} to the print queue.")
|
||||
Catch e As PrintJobException
|
||||
isAllPrinted = False
|
||||
Debug.WriteLine($"Failed to add {xpsFileName} to the print queue: {e.Message}\r\n{e.InnerException}")
|
||||
End Try
|
||||
Next
|
||||
|
||||
Return isAllPrinted
|
||||
|
||||
End Function
|
||||
' </SampleCode1>
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="CodeSampleCsharp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:CodeSampleCsharp"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace CodeSampleCsharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<Window x:Class="CodeSampleCsharp.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="Print an XPS file" Height="234" Width="509">
|
||||
<Grid Margin="0,0,0,-6" Loaded="Grid_Loaded">
|
||||
<Label Content="Select an XPS file" HorizontalAlignment="Left" Margin="27,12,0,0" VerticalAlignment="Top" FontSize="11" Height="25" Width="339"/>
|
||||
<Button Content="Print" HorizontalAlignment="Left" Margin="32,148,0,0" FontSize="14" Width="51" x:Name="btnPrint" Height="28" VerticalAlignment="Top" Click="BtnPrint_Click"/>
|
||||
<ComboBox x:Name="cmbPrinters" HorizontalAlignment="Left" Margin="32,90,0,0" VerticalAlignment="Top" Width="372"/>
|
||||
<Label Content="Select a printer" HorizontalAlignment="Left" Margin="27,66,0,0" VerticalAlignment="Top" FontSize="11" Height="25" Width="339"/>
|
||||
<Button Content="Browse" HorizontalAlignment="Left" Margin="428,35,0,0" VerticalAlignment="Top" Width="48" x:Name="btnBrowse" Height="20" Click="BtnBrowse_Click"/>
|
||||
<TextBox HorizontalAlignment="Left" Margin="32,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="391" FontSize="14" x:Name="txtXpsFilePath" Height="21"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Printing;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Xps;
|
||||
using System.Windows.Xps.Packaging;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace CodeSampleCsharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml.
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow() => InitializeComponent();
|
||||
|
||||
private void Grid_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
foreach (PrintQueue printQueue in GetPrintQueues())
|
||||
{
|
||||
// Add printers that have at least one relevant print options.
|
||||
PrintCapabilities printCapabilites = printQueue.GetPrintCapabilities();
|
||||
if (printCapabilites.CollationCapability.Contains(Collation.Collated) ||
|
||||
printCapabilites.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge) ||
|
||||
printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft))
|
||||
cmbPrinters.Items.Add(printQueue.Name);
|
||||
}
|
||||
|
||||
// Select the first printer.
|
||||
if (cmbPrinters.Items.Count > 0)
|
||||
cmbPrinters.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private void BtnBrowse_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Configure an open file dialog box.
|
||||
OpenFileDialog openFileDialog = new()
|
||||
{
|
||||
FileName = "Document",
|
||||
DefaultExt = ".xps",
|
||||
Filter = "Text documents (.xps)|*.xps"
|
||||
};
|
||||
|
||||
// Show open file dialog box.
|
||||
bool? result = openFileDialog.ShowDialog();
|
||||
|
||||
// Process open file dialog box results.
|
||||
if (result == true)
|
||||
{
|
||||
// Show selected XPS file path.
|
||||
txtXpsFilePath.Text = openFileDialog.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnPrint_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Check the XPS file exists.
|
||||
if (!File.Exists(txtXpsFilePath.Text))
|
||||
{
|
||||
MessageBox.Show("First select an XPS file.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the print queue for the selected printer.
|
||||
PrintQueue selectedPrintQueue = GetPrintQueues().SingleOrDefault(x => Equals(x.Name, cmbPrinters.SelectedItem.ToString()));
|
||||
|
||||
// Get a print ticket with modified print options for the selected printer.
|
||||
PrintTicket printTicket = GetPrintTicket(selectedPrintQueue);
|
||||
|
||||
// Send the XPS document to the selected printer.
|
||||
PrintXpsDocumentAsync(txtXpsFilePath.Text, selectedPrintQueue, printTicket);
|
||||
|
||||
// Show modified print options.
|
||||
List<string> optionList = new();
|
||||
if (printTicket.Collation == Collation.Collated)
|
||||
optionList.Add("Collated");
|
||||
if (printTicket.Duplexing == Duplexing.TwoSidedLongEdge)
|
||||
optionList.Add("TwoSidedLongEdge");
|
||||
if (printTicket.Stapling == Stapling.StapleDualLeft)
|
||||
optionList.Add("StapleDualLeft");
|
||||
var options = optionList.Count > 0 ? string.Join(", ", optionList) : "None";
|
||||
|
||||
// Show result message.
|
||||
MessageBox.Show($"Sent {Path.GetFileName(txtXpsFilePath.Text)} to the printer.\r\nPrint options: {options}");
|
||||
}
|
||||
|
||||
// <GetPrintQueues>
|
||||
/// <summary>
|
||||
/// Return a collection of print queues, which individually hold the features or states
|
||||
/// of a printer as well as common properties for all print queues.
|
||||
/// </summary>
|
||||
/// <returns>A collection of print queues.</returns>
|
||||
public static PrintQueueCollection GetPrintQueues()
|
||||
{
|
||||
// Create a LocalPrintServer instance, which represents
|
||||
// the print server for the local computer.
|
||||
LocalPrintServer localPrintServer = new();
|
||||
|
||||
// Get the default print queue on the local computer.
|
||||
//PrintQueue printQueue = localPrintServer.DefaultPrintQueue;
|
||||
|
||||
// Get all print queues on the local computer.
|
||||
PrintQueueCollection printQueueCollection = localPrintServer.GetPrintQueues();
|
||||
|
||||
// Return a collection of print queues, which individually hold the features or states
|
||||
// of a printer as well as common properties for all print queues.
|
||||
return printQueueCollection;
|
||||
}
|
||||
// </GetPrintQueues>
|
||||
|
||||
// <GetPrintTicket>
|
||||
/// <summary>
|
||||
/// Returns a print ticket, which is a set of instructions telling a printer how
|
||||
/// to set its various features, such as duplexing, collating, and stapling.
|
||||
/// </summary>
|
||||
/// <param name="printQueue">The print queue to print to.</param>
|
||||
/// <returns>A print ticket.</returns>
|
||||
public static PrintTicket GetPrintTicket(PrintQueue printQueue)
|
||||
{
|
||||
PrintCapabilities printCapabilites = printQueue.GetPrintCapabilities();
|
||||
|
||||
// Get a default print ticket from printer.
|
||||
PrintTicket printTicket = printQueue.DefaultPrintTicket;
|
||||
|
||||
// Modify the print ticket.
|
||||
if (printCapabilites.CollationCapability.Contains(Collation.Collated))
|
||||
printTicket.Collation = Collation.Collated;
|
||||
if (printCapabilites.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge))
|
||||
printTicket.Duplexing = Duplexing.TwoSidedLongEdge;
|
||||
if (printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft))
|
||||
printTicket.Stapling = Stapling.StapleDualLeft;
|
||||
|
||||
// Returns a print ticket, which is a set of instructions telling a printer how
|
||||
// to set its various features, such as duplexing, collating, and stapling.
|
||||
return printTicket;
|
||||
}
|
||||
// </GetPrintTicket>
|
||||
|
||||
// <PrintXpsDocument>
|
||||
/// <summary>
|
||||
/// Asynchronously, add the XPS document together with a print ticket to the print queue.
|
||||
/// </summary>
|
||||
/// <param name="xpsFilePath">Path to source XPS file.</param>
|
||||
/// <param name="printQueue">The print queue to print to.</param>
|
||||
/// <param name="printTicket">The print ticket for the selected print queue.</param>
|
||||
public static void PrintXpsDocumentAsync(string xpsFilePath, PrintQueue printQueue, PrintTicket printTicket)
|
||||
{
|
||||
// Create an XpsDocumentWriter object for the print queue.
|
||||
XpsDocumentWriter xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);
|
||||
|
||||
// Open the selected document.
|
||||
XpsDocument xpsDocument = new(xpsFilePath, FileAccess.Read);
|
||||
|
||||
// Get a fixed document sequence for the selected document.
|
||||
FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();
|
||||
|
||||
// Asynchronously, add the XPS document together with a print ticket to the print queue.
|
||||
xpsDocumentWriter.WriteAsync(fixedDocSeq, printTicket);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Synchronously, add the XPS document together with a print ticket to the print queue.
|
||||
/// </summary>
|
||||
/// <param name="xpsFilePath">Path to source XPS file.</param>
|
||||
/// <param name="printQueue">The print queue to print to.</param>
|
||||
/// <param name="printTicket">The print ticket for the selected print queue.</param>
|
||||
public static void PrintXpsDocument(string xpsFilePath, PrintQueue printQueue, PrintTicket printTicket)
|
||||
{
|
||||
// Create an XpsDocumentWriter object for the print queue.
|
||||
XpsDocumentWriter xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);
|
||||
|
||||
// Open the selected document.
|
||||
XpsDocument xpsDocument = new(xpsFilePath, FileAccess.Read);
|
||||
|
||||
// Get a fixed document sequence for the selected document.
|
||||
FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();
|
||||
|
||||
// Synchronously, add the XPS document together with a print ticket to the print queue.
|
||||
xpsDocumentWriter.Write(fixedDocSeq, printTicket);
|
||||
}
|
||||
// </PrintXpsDocument>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="Application"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:CodeSampleVb"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
Class Application
|
||||
|
||||
' Application-level events, such as Startup, Exit, and DispatcherUnhandledException
|
||||
' can be handled in this file.
|
||||
|
||||
End Class
|
||||
@@ -0,0 +1,11 @@
|
||||
Imports System.Windows
|
||||
|
||||
'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found.
|
||||
'1st parameter: where theme specific resource dictionaries are located
|
||||
'(used if a resource is not found in the page,
|
||||
' or application resource dictionaries)
|
||||
|
||||
'2nd parameter: where the generic resource dictionary is located
|
||||
'(used if a resource is not found in the page,
|
||||
'app, and any theme specific resource dictionaries)
|
||||
<Assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<RootNamespace>CodeSampleVb</RootNamespace>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Import Include="System.Windows" />
|
||||
<Import Include="System.Windows.Controls" />
|
||||
<Import Include="System.Windows.Data" />
|
||||
<Import Include="System.Windows.Documents" />
|
||||
<Import Include="System.Windows.Input" />
|
||||
<Import Include="System.Windows.Media" />
|
||||
<Import Include="System.Windows.Media.Imaging" />
|
||||
<Import Include="System.Windows.Navigation" />
|
||||
<Import Include="System.Windows.Shapes" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,16 @@
|
||||
<Window x:Class="CodeSampleVb.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="Print an XPS file" Height="234" Width="509">
|
||||
<Grid Margin="0,0,0,-6" Loaded="Grid_Loaded">
|
||||
<Label Content="Select an XPS file" HorizontalAlignment="Left" Margin="27,12,0,0" VerticalAlignment="Top" FontSize="11" Height="25" Width="339"/>
|
||||
<Button Content="Print" HorizontalAlignment="Left" Margin="32,148,0,0" FontSize="14" Width="51" x:Name="btnPrint" Height="28" VerticalAlignment="Top" Click="BtnPrint_Click"/>
|
||||
<ComboBox x:Name="cmbPrinters" HorizontalAlignment="Left" Margin="32,90,0,0" VerticalAlignment="Top" Width="372"/>
|
||||
<Label Content="Select a printer" HorizontalAlignment="Left" Margin="27,66,0,0" VerticalAlignment="Top" FontSize="11" Height="25" Width="339"/>
|
||||
<Button Content="Browse" HorizontalAlignment="Left" Margin="428,35,0,0" VerticalAlignment="Top" Width="48" x:Name="btnBrowse" Height="20" Click="BtnBrowse_Click"/>
|
||||
<TextBox HorizontalAlignment="Left" Margin="32,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="391" FontSize="14" x:Name="txtXpsFilePath" Height="21"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
Imports System.IO
|
||||
Imports System.Printing
|
||||
Imports System.Windows.Xps
|
||||
Imports System.Windows.Xps.Packaging
|
||||
Imports Microsoft.Win32
|
||||
|
||||
Namespace CodeSampleVb
|
||||
Partial Public Class MainWindow
|
||||
Inherits Window
|
||||
|
||||
''' <summary>
|
||||
''' Interaction logic for MainWindow.xaml
|
||||
''' </summary>
|
||||
Public Sub New()
|
||||
|
||||
InitializeComponent()
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub Grid_Loaded(sender As Object, e As RoutedEventArgs)
|
||||
|
||||
For Each printQueue As PrintQueue In GetPrintQueues()
|
||||
' Add printers that have at least one relevant print options.
|
||||
Dim printCapabilites As PrintCapabilities = printQueue.GetPrintCapabilities()
|
||||
|
||||
If printCapabilites.CollationCapability.Contains(Collation.Collated) _
|
||||
OrElse printCapabilites.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge) _
|
||||
OrElse printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft) Then
|
||||
cmbPrinters.Items.Add(printQueue.Name)
|
||||
End If
|
||||
Next
|
||||
|
||||
' Select the first printer.
|
||||
If cmbPrinters.Items.Count > 0 Then cmbPrinters.SelectedIndex = 0
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub BtnBrowse_Click(sender As Object, e As RoutedEventArgs)
|
||||
|
||||
' Configure an open file dialog box.
|
||||
Dim openFileDialog As OpenFileDialog = New OpenFileDialog() With {
|
||||
.FileName = "Document",
|
||||
.DefaultExt = ".xps",
|
||||
.Filter = "Text documents (.xps)|*.xps"
|
||||
}
|
||||
|
||||
' Show open file dialog box.
|
||||
Dim result As Boolean? = openFileDialog.ShowDialog()
|
||||
|
||||
' Process open file dialog box results.
|
||||
If result = True Then
|
||||
' Show selected XPS file path.
|
||||
txtXpsFilePath.Text = openFileDialog.FileName
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub BtnPrint_Click(sender As Object, e As RoutedEventArgs)
|
||||
|
||||
' Check the XPS file exists.
|
||||
If Not File.Exists(txtXpsFilePath.Text) Then
|
||||
MessageBox.Show("First select an XPS file.")
|
||||
Return
|
||||
End If
|
||||
|
||||
' Get the print queue for the selected printer.
|
||||
Dim selectedPrintQueue As PrintQueue = GetPrintQueues().SingleOrDefault(Function(x) Equals(x.Name, cmbPrinters.SelectedItem.ToString()))
|
||||
|
||||
' Get a print ticket with modified print options for the selected printer.
|
||||
Dim printTicket As PrintTicket = GetPrintTicket(selectedPrintQueue)
|
||||
|
||||
' Send the XPS document to the selected printer.
|
||||
PrintXpsDocumentAsync(txtXpsFilePath.Text, selectedPrintQueue, printTicket)
|
||||
|
||||
' Show modified print options.
|
||||
Dim optionList As List(Of String) = New List(Of String)()
|
||||
If printTicket.Collation = Collation.Collated Then optionList.Add("Collated")
|
||||
If printTicket.Duplexing = Duplexing.TwoSidedLongEdge Then optionList.Add("TwoSidedLongEdge")
|
||||
If printTicket.Stapling = Stapling.StapleDualLeft Then optionList.Add("StapleDualLeft")
|
||||
Dim options = If(optionList.Count > 0, String.Join(", ", optionList), "None")
|
||||
|
||||
' Show result message.
|
||||
MessageBox.Show($"Sent {Path.GetFileName(txtXpsFilePath.Text)} to the printer.{vbCrLf}Print options: {options}")
|
||||
End Sub
|
||||
|
||||
' <GetPrintQueues>
|
||||
''' <summary>
|
||||
''' Return a collection of print queues, which individually hold the features or states
|
||||
''' of a printer as well as common properties for all print queues.
|
||||
''' </summary>
|
||||
''' <returns>A collection of print queues.</returns>
|
||||
Public Shared Function GetPrintQueues() As PrintQueueCollection
|
||||
|
||||
' Create a LocalPrintServer instance, which represents
|
||||
' the print server for the local computer.
|
||||
Dim localPrintServer As LocalPrintServer = New LocalPrintServer()
|
||||
|
||||
' Get the default print queue on the local computer.
|
||||
'Dim printQueue As PrintQueue = localPrintServer.DefaultPrintQueue
|
||||
|
||||
' Get all print queues on the local computer.
|
||||
Dim printQueueCollection As PrintQueueCollection = localPrintServer.GetPrintQueues()
|
||||
|
||||
' Return a collection of print queues, which individually hold the features or states
|
||||
' of a printer as well as common properties for all print queues.
|
||||
Return printQueueCollection
|
||||
|
||||
End Function
|
||||
' </GetPrintQueues>
|
||||
|
||||
' <GetPrintTicket>
|
||||
''' <summary>
|
||||
''' Returns a print ticket, which is a set of instructions telling a printer how
|
||||
''' to set its various features, such as duplexing, collating, and stapling.
|
||||
''' </summary>
|
||||
''' <param name="printQueue">The print queue to print to.</param>
|
||||
''' <returns>A print ticket.</returns>
|
||||
Public Shared Function GetPrintTicket(printQueue As PrintQueue) As PrintTicket
|
||||
|
||||
Dim printCapabilites As PrintCapabilities = printQueue.GetPrintCapabilities()
|
||||
|
||||
' Get a default print ticket from printer.
|
||||
Dim printTicket As PrintTicket = printQueue.DefaultPrintTicket
|
||||
|
||||
' Modify the print ticket.
|
||||
If printCapabilites.CollationCapability.Contains(Collation.Collated) Then
|
||||
printTicket.Collation = Collation.Collated
|
||||
End If
|
||||
If printCapabilites.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge) Then
|
||||
printTicket.Duplexing = Duplexing.TwoSidedLongEdge
|
||||
End If
|
||||
If printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft) Then
|
||||
printTicket.Stapling = Stapling.StapleDualLeft
|
||||
End If
|
||||
|
||||
' Returns a print ticket, which is a set of instructions telling a printer how
|
||||
' to set its various features, such as duplexing, collating, and stapling.
|
||||
Return printTicket
|
||||
|
||||
End Function
|
||||
' </GetPrintTicket>
|
||||
|
||||
' <PrintXpsDocument>
|
||||
''' <summary>
|
||||
''' Asynchronously, add the XPS document together with a print ticket to the print queue.
|
||||
''' </summary>
|
||||
''' <param name="xpsFilePath">Path to source XPS file.</param>
|
||||
''' <param name="printQueue">The print queue to print to.</param>
|
||||
''' <param name="printTicket">The print ticket for the selected print queue.</param>
|
||||
Public Shared Sub PrintXpsDocumentAsync(xpsFilePath As String, printQueue As PrintQueue, printTicket As PrintTicket)
|
||||
|
||||
' Create an XpsDocumentWriter object for the print queue.
|
||||
Dim xpsDocumentWriter As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue)
|
||||
|
||||
' Open the selected document.
|
||||
Dim xpsDocument As XpsDocument = New XpsDocument(xpsFilePath, FileAccess.Read)
|
||||
|
||||
' Get a fixed document sequence for the selected document.
|
||||
Dim fixedDocSeq As FixedDocumentSequence = xpsDocument.GetFixedDocumentSequence()
|
||||
|
||||
' Asynchronously, add the XPS document together with a print ticket to the print queue.
|
||||
xpsDocumentWriter.WriteAsync(fixedDocSeq, printTicket)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Synchronously, add the XPS document together with a print ticket to the print queue.
|
||||
''' </summary>
|
||||
''' <param name="xpsFilePath">Path to source XPS file.</param>
|
||||
''' <param name="printQueue">The print queue to print to.</param>
|
||||
''' <param name="printTicket">The print ticket for the selected print queue.</param>
|
||||
Public Shared Sub PrintXpsDocument(xpsFilePath As String, printQueue As PrintQueue, printTicket As PrintTicket)
|
||||
|
||||
' Create an XpsDocumentWriter object for the print queue.
|
||||
Dim xpsDocumentWriter As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue)
|
||||
|
||||
' Open the selected document.
|
||||
Dim xpsDocument As XpsDocument = New XpsDocument(xpsFilePath, FileAccess.Read)
|
||||
|
||||
' Get a fixed document sequence for the selected document.
|
||||
Dim fixedDocSeq As FixedDocumentSequence = xpsDocument.GetFixedDocumentSequence()
|
||||
|
||||
' Synchronously, add the XPS document together with a print ticket to the print queue.
|
||||
xpsDocumentWriter.Write(fixedDocSeq, printTicket)
|
||||
|
||||
End Sub
|
||||
' </PrintXpsDocument>
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
Reference in New Issue
Block a user