Mencetak dari aplikasi Anda
Topik ini menjelaskan cara mencetak dari aplikasi Windows.
Untuk fitur tingkat lanjut lainnya, lihat Mengkustomisasi antarmuka pengguna pratinjau cetak.
- API Penting: Namespace layanan Windows.Graphics.Printing, kelas PrintManager, PrintTask, Microsoft.UI.Xaml.Printing namespace, kelas PrintDocument
Daftar untuk pencetakan
Langkah pertama untuk menambahkan pencetakan ke aplikasi Anda adalah mendaftar untuk mencetak dengan mendapatkan objek PrintManager untuk jendela saat ini. Kelas PrintManager bertanggung jawab untuk mengatur alur pencetakan untuk aplikasi Anda. Untuk menggunakan kelas ini, Anda harus terlebih dahulu memanggil metode yang mengembalikan objek PrintManager yang khusus untuk jendela aktif saat ini.
- Di aplikasi non-UWP, gunakan metode PrintManagerInterop.GetForWindow .
- Di aplikasi UWP, gunakan metode PrintManager.GetForCurrentView .
Aplikasi Anda harus melakukan ini di setiap layar tempat Anda ingin pengguna Anda dapat mencetak. Hanya layar yang ditampilkan kepada pengguna yang dapat didaftarkan untuk pencetakan. Jika satu layar aplikasi Anda telah terdaftar untuk pencetakan, layar harus membatalkan pendaftaran untuk pencetakan saat keluar. Jika digantikan oleh layar lain, layar berikutnya harus mendaftar untuk mencetak ketika terbuka.
Tip
Jika Anda perlu mendukung pencetakan dari lebih dari satu halaman di aplikasi, Anda dapat menempatkan kode cetak ini di kelas pembantu umum dan meminta halaman aplikasi Anda menggunakannya kembali. Untuk contoh cara melakukan ini, lihat PrintHelper
kelas dalam sampel cetak UWP.
Setelah pengguna memulai pencetakan, Anda menggunakan PrintDocument untuk menyiapkan halaman yang akan dikirim ke printer. PrintDocument
Jenisnya ada di namespace Microsoft.UI.Xaml.Printing bersama dengan jenis lain yang mendukung persiapan konten XAML untuk pencetakan.
Kelas PrintDocument digunakan untuk menangani banyak interaksi antara aplikasi dan PrintManager, tetapi mengekspos beberapa panggilan baliknya sendiri. Selama pendaftaran, buat instans PrintManager
dan PrintDocument
daftarkan handler untuk peristiwa pencetakan mereka.
Dalam contoh ini, pendaftaran dilakukan dalam RegisterForPrinting
metode , yang dipanggil dari penangan aktivitas Yang Dimuat halaman.
using Microsoft.UI.Xaml.Printing;
using Windows.Graphics.Printing;
PrintDocument printDocument = null;
IPrintDocumentSource printDocumentSource = null;
List<UIElement> printPreviewPages = new List<UIElement>();
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
RegisterForPrinting();
}
private void RegisterForPrinting()
{
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
PrintManager printManager = PrintManagerInterop.GetForWindow(hWnd);
printManager.PrintTaskRequested += PrintTask_Requested;
printDocument = new PrintDocument();
printDocumentSource = printDocument.DocumentSource;
printDocument.Paginate += PrintDocument_Paginate;
printDocument.GetPreviewPage += PrintDocument_GetPreviewPage;
printDocument.AddPages += PrintDocument_AddPages;
}
Peringatan
Dalam contoh pencetakan UWP, disarankan untuk mendaftar untuk mencetak dari penimpaan metode OnNavigatedTo. Di aplikasi non-UWP, Anda perlu menggunakan handel jendela di panggilan PrintManagerInterop.GetForWindow, jadi Anda harus menggunakan peristiwa Dimuat untuk memastikan bahwa handel jendela tidak null
, yang mungkin terjadi di OnNavigatedTo.
Di sini, penanganan aktivitas tidak terdaftar dalam UnregisterForPrinting
metode , yang dipanggil dari metode OnNavigatedFrom .
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
UnregisterForPrinting();
}
private void UnregisterForPrinting()
{
if (printDocument == null)
{
return;
}
printDocument.Paginate -= PrintDocument_Paginate;
printDocument.GetPreviewPage -= PrintDocument_GetPreviewPage;
printDocument.AddPages -= PrintDocument_AddPages;
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
PrintManager printManager = PrintManagerInterop.GetForWindow(hWnd);
printManager.PrintTaskRequested -= PrintTask_Requested;
}
Catatan
Jika Anda memiliki aplikasi beberapa halaman dan tidak memutuskan sambungan pencetakan, pengecualian akan dilemparkan saat pengguna meninggalkan halaman lalu kembali ke halaman tersebut.
Tombol Buat cetak
Tambahkan tombol cetak ke layar aplikasi tempat Anda ingin menampilkannya. Pastikan konten tidak mengganggu konten yang ingin Anda cetak.
<Button x:Name="InvokePrintingButton"
Content="Print"
Click="InvokePrintingButton_Click"/>
Di handler aktivitas Klik Tombol, perlihatkan UI cetak Windows kepada pengguna.
- Dalam aplikasi non-UWP, gunakan metode PrintManagerInterop.ShowPrintUIForWindowAsync .
- Di aplikasi UWP, gunakan metode PrintManager.ShowPrintUIAsync .
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
await PrintManagerInterop.ShowPrintUIForWindowAsync(hWnd);
Metode ini adalah metode asinkron yang menampilkan jendela pencetakan yang sesuai, jadi Anda harus menambahkan kata kunci asinkron ke penangan Klik. Sebaiknya panggil metode IsSupported terlebih dahulu untuk memeriksa apakah aplikasi sedang dijalankan pada perangkat yang mendukung pencetakan (dan menangani kasus di mana tidak). Jika pencetakan tidak dapat dilakukan pada saat itu karena alasan lain, metode akan melemparkan pengecualian. Sebaiknya tangkap pengecualian ini dan beri tahu pengguna kapan pencetakan tidak dapat dilanjutkan.
Dalam contoh ini, jendela cetak ditampilkan di penanganan aktivitas untuk klik tombol. Jika metode melemparkan pengecualian (karena pencetakan tidak dapat dilakukan pada saat itu), kontrol ContentDialog memberi tahu pengguna tentang situasi tersebut.
private async void InvokePrintingButton_Click(object sender, RoutedEventArgs e)
{
if (PrintManager.IsSupported())
{
try
{
// Show system print UI.
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
await Windows.Graphics.Printing.PrintManagerInterop.ShowPrintUIForWindowAsync(hWnd);
}
catch
{
// Printing cannot proceed at this time.
ContentDialog noPrintingDialog = new ContentDialog()
{
Title = "Printing error",
Content = "\nSorry, printing can' t proceed at this time.",
PrimaryButtonText = "OK"
};
await noPrintingDialog.ShowAsync();
}
}
else
{
// Printing is not supported on this device.
ContentDialog noPrintingDialog = new ContentDialog()
{
Title = "Printing not supported",
Content = "\nSorry, printing is not supported on this device.",
PrimaryButtonText = "OK"
};
await noPrintingDialog.ShowAsync();
}
}
Memformat konten aplikasi Anda
Ketika ShowPrintUIForWindowAsync
dipanggil, peristiwa PrintTaskRequested dinaikkan. Di penanganan PrintTaskRequested
aktivitas, Anda membuat PrintTask dengan memanggil metode PrintTaskRequest.CreatePrintTask . Berikan judul untuk halaman cetak dan nama delegasi PrintTaskSourceRequestedHandler . Judul ditampilkan di antarmuka pengguna pratinjau cetak. Tautan PrintTaskSourceRequestedHandler
PrintTask
dengan PrintDocument
yang akan menyediakan konten.
Dalam contoh ini, handler penyelesaian juga didefinisikan untuk menangkap kesalahan. Ada baiknya menangani peristiwa penyelesaian karena aplikasi Anda dapat memberi tahu pengguna jika terjadi kesalahan dan memberikan solusi yang mungkin. Demikian juga, aplikasi Anda dapat menggunakan peristiwa penyelesaian untuk menunjukkan langkah-langkah berikutnya yang harus dilakukan pengguna setelah pekerjaan cetak berhasil.
private void PrintTask_Requested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
// Create the PrintTask.
// Defines the title and delegate for PrintTaskSourceRequested.
PrintTask printTask = args.Request.CreatePrintTask("WinUI 3 Printing example", PrintTaskSourceRequested);
// Handle PrintTask.Completed to catch failed print jobs.
printTask.Completed += PrintTask_Completed;
DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
{
InvokePrintingButton.IsEnabled = false;
});
}
private void PrintTaskSourceRequested(PrintTaskSourceRequestedArgs args)
{
// Set the document source.
args.SetSource(printDocumentSource);
}
private void PrintTask_Completed(PrintTask sender, PrintTaskCompletedEventArgs args)
{
string StatusBlockText = string.Empty;
// Notify the user if the print operation fails.
if (args.Completion == PrintTaskCompletion.Failed)
{
StatusBlockText = "Failed to print.";
}
else if (args.Completion == PrintTaskCompletion.Canceled)
{
StatusBlockText = "Printing canceled.";
}
else
{
StatusBlockText = "Printing completed.";
}
DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
{
StatusBlock.Text = StatusBlockText;
InvokePrintingButton.IsEnabled = true;
});
}
Setelah tugas cetak dibuat, PrintManager meminta kumpulan halaman cetak untuk ditampilkan di antarmuka pengguna pratinjau cetak dengan menaikkan peristiwa Paginate . (Ini sesuai dengan Paginate
metode IPrintPreviewPageCollection
antarmuka.) Penanganan aktivitas yang Anda buat selama pendaftaran dipanggil saat ini.
Penting
Jika pengguna mengubah pengaturan cetak, penanganan aktivitas paginasi akan dipanggil lagi untuk memungkinkan Anda me-reflow konten. Untuk pengalaman pengguna terbaik, sebaiknya periksa pengaturan sebelum Anda me-reflow konten dan hindari menginisialisasi ulang konten paginated saat tidak diperlukan.
Di penanganan aktivitas Paginate , buat halaman untuk ditampilkan di antarmuka pengguna pratinjau cetak dan untuk dikirim ke printer. Kode yang Anda gunakan untuk menyiapkan konten aplikasi untuk pencetakan khusus untuk aplikasi Anda dan konten yang Anda cetak.
Contoh ini memperlihatkan langkah-langkah dasar untuk membuat satu halaman cetak yang mencetak gambar dan keterangan dari halaman yang diperlihatkan di layar.
- Buat daftar untuk menahan elemen UI (halaman) yang akan dicetak.
- Hapus daftar halaman pratinjau sehingga halaman tidak diduplikasi setiap kali penomoran halaman terjadi.
- Gunakan PrintPageDescription untuk mendapatkan ukuran halaman printer.
- Format isi XAML Anda agar pas dengan halaman printer. Setiap halaman yang akan dicetak adalah elemen UI XAML (biasanya elemen kontainer yang berisi konten lain). Dalam contoh ini, elemen dibuat dalam kode dan menggunakan data yang sama dengan elemen yang ditunjukkan pada layar.
- Mengalirkan konten ke halaman tambahan sesuai kebutuhan. Beberapa halaman tidak ditampilkan dalam contoh dasar ini, tetapi membalik konten menjadi halaman adalah bagian penting dari peristiwa Paginate.
- Tambahkan setiap halaman ke daftar halaman yang akan dicetak.
- Atur jumlah halaman pratinjau pada PrintDocument.
List<UIElement> printPreviewPages = new List<UIElement>();
private void PrintDocument_Paginate(object sender, PaginateEventArgs e)
{
// Clear the cache of preview pages.
printPreviewPages.Clear();
// Get the PrintTaskOptions.
PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);
// Get the page description to determine the size of the print page.
PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);
// Create the print layout.
StackPanel printLayout = new StackPanel();
printLayout.Width = pageDescription.PageSize.Width;
printLayout.Height = pageDescription.PageSize.Height;
printLayout.BorderBrush = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Black);
printLayout.BorderThickness = new Thickness(48);
Image printImage = new Image();
printImage.Source = printContent.Source;
printImage.Width = pageDescription.PageSize.Width / 2;
printImage.Height = pageDescription.PageSize.Height / 2;
TextBlock imageDescriptionText = new TextBlock();
imageDescriptionText.Text = imageDescription.Text;
imageDescriptionText.FontSize = 24;
imageDescriptionText.HorizontalAlignment = HorizontalAlignment.Center;
imageDescriptionText.Width = pageDescription.PageSize.Width / 2;
imageDescriptionText.TextWrapping = TextWrapping.WrapWholeWords;
printLayout.Children.Add(printImage);
printLayout.Children.Add(imageDescriptionText);
// Add the print layout to the list of preview pages.
printPreviewPages.Add(printLayout);
// Report the number of preview pages created.
PrintDocument printDocument = (PrintDocument)sender;
printDocument.SetPreviewPageCount(printPreviewPages.Count,
PreviewPageCountType.Intermediate);
}
Berikut adalah cuplikan layar UI aplikasi dan bagaimana konten muncul di antarmuka pengguna pratinjau cetak.
Saat halaman tertentu akan ditampilkan di jendela pratinjau cetak, PrintManager menaikkan peristiwa GetPreviewPage . Ini sesuai dengan MakePage
metode IPrintPreviewPageCollection
antarmuka. Penanganan aktivitas yang Anda buat selama pendaftaran dipanggil saat ini.
Di penanganan aktivitas GetPreviewPage , atur halaman yang sesuai pada dokumen cetak.
private void PrintDocument_GetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
PrintDocument printDocument = (PrintDocument)sender;
printDocument.SetPreviewPage(e.PageNumber, printPreviewPages[e.PageNumber - 1]);
}
Terakhir, setelah pengguna mengklik tombol cetak, PrintManager meminta kumpulan halaman akhir untuk dikirim ke printer dengan memanggil MakeDocument
metode IDocumentPageSource
antarmuka. Di XAML, ini meningkatkan peristiwa AddPages . Penanganan aktivitas yang Anda buat selama pendaftaran dipanggil saat ini.
Di penanganan aktivitas AddPages , tambahkan halaman dari kumpulan halaman ke objek PrintDocument yang akan dikirim ke printer. Jika pengguna menentukan halaman tertentu atau rentang halaman yang akan dicetak, Anda menggunakan informasi tersebut di sini untuk menambahkan hanya halaman yang benar-benar akan dikirim ke pencetak.
private void PrintDocument_AddPages(object sender, AddPagesEventArgs e)
{
PrintDocument printDocument = (PrintDocument)sender;
// Loop over all of the preview pages and add each one to be printed.
for (int i = 0; i < printPreviewPages.Count; i++)
{
printDocument.AddPage(printPreviewPages[i]);
}
// Indicate that all of the print pages have been provided.
printDocument.AddPagesComplete();
}
Topik terkait
Windows developer