Bagikan melalui


Mencetak dari aplikasi Anda

Topik ini menjelaskan cara mencetak dari aplikasi Universal Windows.

Untuk fitur tingkat lanjut lainnya, lihat Mengkustomisasi antarmuka pengguna pratinjau cetak.

API penting

Tip

 Sebagian besar contoh dalam topik ini didasarkan pada sampel cetak Platform Windows Universal (UWP), yang merupakan bagian dari repositori sampel aplikasi Platform Windows Universal (UWP) di GitHub.

Daftar untuk pencetakan

Langkah pertama untuk menambahkan pencetakan ke aplikasi Anda adalah mendaftar untuk kontrak Cetak. 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 kontrak Cetak baru saat dibuka.

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.

Pertama, deklarasikan PrintManager dan PrintDocument. Tipe PrintManager ada di namespace Windows.Graphics.Printing bersama dengan tipe untuk mendukung fungsionalitas pencetakan Windows lainnya. Jenis PrintDocument ada di namespace Layanan Windows.UI.Xaml.Printing bersama dengan jenis lain yang mendukung persiapan konten XAML untuk pencetakan. Anda dapat mempermudah penulisan kode pencetakan Anda dengan menambahkan pernyataan berikut ini menggunakan atau Mengimpor ke halaman Anda.

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

Kelas PrintDocument digunakan untuk menangani banyak interaksi antara aplikasi dan PrintManager, tetapi mengekspos beberapa panggilan baliknya sendiri. Selama pendaftaran, buat instans PrintManager dan PrintDocument dan daftarkan handler untuk peristiwa pencetakan mereka.

Dalam sampel cetak UWP, pendaftaran dilakukan dengan RegisterForPrinting metode .

public virtual void RegisterForPrinting()
{
   printDocument = new PrintDocument();
   printDocumentSource = printDocument.DocumentSource;
   printDocument.Paginate += CreatePrintPreviewPages;
   printDocument.GetPreviewPage += GetPrintPreviewPage;
   printDocument.AddPages += AddPrintPages;

   PrintManager printMan = PrintManager.GetForCurrentView();
   printMan.PrintTaskRequested += PrintTaskRequested;
}

Ketika pengguna masuk ke halaman yang mendukung pencetakan, pengguna memulai pendaftaran dalam OnNavigatedTo metode .

protected override void OnNavigatedTo(NavigationEventArgs e)
{
   // Initialize common helper class and register for printing
   printHelper = new PrintHelper(this);
   printHelper.RegisterForPrinting();

   // Initialize print content for this scenario
   printHelper.PreparePrintContent(new PageToPrint());

   // Tell the user how to print
   MainPage.Current.NotifyUser("Print contract registered with customization, use the Print button to print.", NotifyType.StatusMessage);
}

Dalam sampel, penanganan aktivitas tidak terdaftar dalam UnregisterForPrinting metode .

public virtual void UnregisterForPrinting()
{
    if (printDocument == null)
    {
        return;
    }

    printDocument.Paginate -= CreatePrintPreviewPages;
    printDocument.GetPreviewPage -= GetPrintPreviewPage;
    printDocument.AddPages -= AddPrintPages;

    PrintManager printMan = PrintManager.GetForCurrentView();
    printMan.PrintTaskRequested -= PrintTaskRequested;
}

Ketika pengguna meninggalkan halaman yang mendukung pencetakan, penanganan aktivitas tidak terdaftar dalam OnNavigatedFrom metode .

Catatan

Jika Anda memiliki aplikasi beberapa halaman dan tidak memutuskan sambungan pencetakan, pengecualian akan dilemparkan saat pengguna meninggalkan halaman lalu kembali ke halaman tersebut.

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
   if (printHelper != null)
   {
         printHelper.UnregisterForPrinting();
   }
}

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="OnPrintButtonClick"/>

Selanjutnya, tambahkan penanganan aktivitas ke kode aplikasi Anda untuk menangani peristiwa klik. Gunakan metode ShowPrintUIAsync untuk mulai mencetak dari aplikasi Anda. ShowPrintUIAsync adalah metode asinkron yang menampilkan jendela pencetakan yang sesuai. 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, ShowPrintUIAsync akan memberikan 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.

async private void OnPrintButtonClick(object sender, RoutedEventArgs e)
{
    if (Windows.Graphics.Printing.PrintManager.IsSupported())
    {
        try
        {
            // Show print UI
            await Windows.Graphics.Printing.PrintManager.ShowPrintUIAsync();

        }
        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 ShowPrintUIAsync dipanggil, peristiwa PrintTaskRequested dinaikkan. Penanganan aktivitas PrintTaskRequested yang diperlihatkan dalam langkah ini membuat PrintTask dengan memanggil metode PrintTaskRequest.CreatePrintTask dan meneruskan judul untuk halaman cetak dan nama delegasi PrintTaskSourceRequestedHandler. Perhatikan bahwa dalam contoh ini, PrintTaskSourceRequestedHandler didefinisikan sebaris. PrintTaskSourceRequestedHandler menyediakan konten yang diformat untuk pencetakan dan dijelaskan nanti.

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.

protected virtual void PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs e)
{
   PrintTask printTask = null;
   printTask = e.Request.CreatePrintTask("C# Printing SDK Sample", sourceRequested =>
   {
         // Print Task event handler is invoked when the print job is completed.
         printTask.Completed += async (s, args) =>
         {
            // Notify the user when the print operation fails.
            if (args.Completion == PrintTaskCompletion.Failed)
            {
               await scenarioPage.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
               {
                     MainPage.Current.NotifyUser("Failed to print.", NotifyType.ErrorMessage);
               });
            }
         };

         sourceRequested.SetSource(printDocumentSource);
   });
}

Setelah tugas cetak dibuat, PrintManager meminta kumpulan halaman cetak untuk ditampilkan di antarmuka pengguna pratinjau cetak dengan menaikkan peristiwa Paginate. Ini sesuai dengan metode Paginate dari antarmuka IPrintPreviewPageCollection . Penanganan aktivitas yang Anda buat selama pendaftaran akan 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 (CreatePrintPreviewPagesmetode dalam sampel cetak UWP), 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. Lihat kode sumber sampel cetak UWP untuk melihat cara memformat kontennya untuk pencetakan.

protected virtual void CreatePrintPreviewPages(object sender, PaginateEventArgs e)
{
   // Clear the cache of preview pages
   printPreviewPages.Clear();

   // Clear the print canvas of preview pages
   PrintCanvas.Children.Clear();

   // This variable keeps track of the last RichTextBlockOverflow element that was added to a page which will be printed
   RichTextBlockOverflow lastRTBOOnPage;

   // Get the PrintTaskOptions
   PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);

   // Get the page description to deterimine how big the page is
   PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);

   // We know there is at least one page to be printed. passing null as the first parameter to
   // AddOnePrintPreviewPage tells the function to add the first page.
   lastRTBOOnPage = AddOnePrintPreviewPage(null, pageDescription);

   // We know there are more pages to be added as long as the last RichTextBoxOverflow added to a print preview
   // page has extra content
   while (lastRTBOOnPage.HasOverflowContent && lastRTBOOnPage.Visibility == Windows.UI.Xaml.Visibility.Visible)
   {
         lastRTBOOnPage = AddOnePrintPreviewPage(lastRTBOOnPage, pageDescription);
   }

   if (PreviewPagesCreated != null)
   {
         PreviewPagesCreated.Invoke(printPreviewPages, null);
   }

   PrintDocument printDoc = (PrintDocument)sender;

   // Report the number of preview pages created
   printDoc.SetPreviewPageCount(printPreviewPages.Count, PreviewPageCountType.Intermediate);
}

Saat halaman tertentu akan ditampilkan di jendela pratinjau cetak, PrintManager menaikkan peristiwa GetPreviewPage. Ini sesuai dengan metode MakePage antarmuka IPrintPreviewPageCollection . Penanganan aktivitas yang Anda buat selama pendaftaran akan dipanggil saat ini.

Di penanganan aktivitas GetPreviewPage (GetPrintPreviewPagemetode dalam sampel cetak UWP), atur halaman yang sesuai pada dokumen cetak.

protected virtual void GetPrintPreviewPage(object sender, GetPreviewPageEventArgs e)
{
   PrintDocument printDoc = (PrintDocument)sender;
   printDoc.SetPreviewPage(e.PageNumber, printPreviewPages[e.PageNumber - 1]);
}

Akhirnya, setelah pengguna mengklik tombol cetak, PrintManager meminta kumpulan halaman akhir untuk dikirim ke printer dengan memanggil metode MakeDocument antarmuka IDocumentPageSource. Di XAML, ini meningkatkan peristiwa AddPages. Penanganan aktivitas yang Anda buat selama pendaftaran akan dipanggil saat ini.

Di penanganan aktivitas AddPages (AddPrintPagesmetode dalam sampel cetak UWP), 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.

protected virtual void AddPrintPages(object sender, AddPagesEventArgs e)
{
   // Loop over all of the preview pages and add each one to  add each page to be printied
   for (int i = 0; i < printPreviewPages.Count; i++)
   {
         // We should have all pages ready at this point...
         printDocument.AddPage(printPreviewPages[i]);
   }

   PrintDocument printDoc = (PrintDocument)sender;

   // Indicate that all of the print pages have been provided
   printDoc.AddPagesComplete();
}

Menyiapkan opsi cetak

Selanjutnya siapkan opsi cetak. Sebagai contoh, bagian ini akan menjelaskan cara mengatur opsi rentang halaman untuk memungkinkan pencetakan halaman tertentu. Untuk opsi tingkat lanjut lainnya, lihat Mengkustomisasi antarmuka pengguna pratinjau cetak.

Langkah ini membuat opsi cetak baru, menentukan daftar nilai yang didukung opsi, lalu menambahkan opsi ke antarmuka pengguna pratinjau cetak. Opsi rentang halaman memiliki pengaturan ini:

Nama opsi Perbuatan
Cetak semua Cetak semua halaman dalam dokumen.
Pilihan Cetak Cetak hanya isi yang dipilih pengguna.
Rentang Cetak Tampilkan kontrol edit tempat pengguna bisa memasukkan halaman yang akan dicetak.

Pertama, ubah penanganan aktivitas PrintTaskRequested untuk menambahkan kode untuk mendapatkan objek PrintTaskOptionDetails.

PrintTaskOptionDetails printDetailedOptions = PrintTaskOptionDetails.GetFromPrintTaskOptions(printTask.Options);

Hapus daftar opsi yang ditampilkan di antarmuka pengguna pratinjau cetak dan tambahkan opsi yang ingin Anda tampilkan saat pengguna ingin mencetak dari aplikasi.

Catatan

 Opsi muncul di antarmuka pengguna pratinjau cetak dalam urutan yang sama dengan yang ditambahkan, dengan opsi pertama ditampilkan di bagian atas jendela.

IList<string> displayedOptions = printDetailedOptions.DisplayedOptions;

displayedOptions.Clear();
displayedOptions.Add(Windows.Graphics.Printing.StandardPrintTaskOptions.Copies);
displayedOptions.Add(Windows.Graphics.Printing.StandardPrintTaskOptions.Orientation);
displayedOptions.Add(Windows.Graphics.Printing.StandardPrintTaskOptions.ColorMode);

Buat opsi cetak baru dan inisialisasi daftar nilai opsi.

// Create a new list option
PrintCustomItemListOptionDetails pageFormat = printDetailedOptions.CreateItemListOption("PageRange", "Page Range");
pageFormat.AddItem("PrintAll", "Print all");
pageFormat.AddItem("PrintSelection", "Print Selection");
pageFormat.AddItem("PrintRange", "Print Range");

Tambahkan opsi cetak kustom Anda dan tetapkan penanganan aktivitas. Opsi kustom ditambahkan terakhir sehingga muncul di bagian bawah daftar opsi. Tetapi Anda dapat meletakkannya di mana saja dalam daftar, opsi cetak kustom tidak perlu ditambahkan terakhir.

// Add the custom option to the option list
displayedOptions.Add("PageRange");

// Create new edit option
PrintCustomTextOptionDetails pageRangeEdit = printDetailedOptions.CreateTextOption("PageRangeEdit", "Range");

// Register the handler for the option change event
printDetailedOptions.OptionChanged += printDetailedOptions_OptionChanged;

Metode CreateTextOption membuat kotak teks Rentang . Di sinilah pengguna memasukkan halaman tertentu yang ingin mereka cetak saat mereka memilih opsi Rentang Cetak.

Menangani perubahan opsi cetak

Penanganan aktivitas OptionChanged melakukan dua hal. Pertama, ini memperlihatkan dan menyembunyikan bidang edit teks untuk rentang halaman tergantung pada opsi rentang halaman yang dipilih pengguna. Kedua, ini menguji teks yang dimasukkan ke dalam kotak teks rentang halaman untuk memastikan bahwa teks mewakili rentang halaman yang valid untuk dokumen.

Contoh ini menunjukkan bagaimana opsi cetak mengubah peristiwa ditangani dalam sampel cetak UWP.

async void printDetailedOptions_OptionChanged(PrintTaskOptionDetails sender, PrintTaskOptionChangedEventArgs args)
{
   if (args.OptionId == null)
   {
         return;
   }

   string optionId = args.OptionId.ToString();

   // Handle change in Page Range Option
   if (optionId == "PageRange")
   {
         IPrintOptionDetails pageRange = sender.Options[optionId];
         string pageRangeValue = pageRange.Value.ToString();

         selectionMode = false;

         switch (pageRangeValue)
         {
            case "PrintRange":
               // Add PageRangeEdit custom option to the option list
               sender.DisplayedOptions.Add("PageRangeEdit");
               pageRangeEditVisible = true;
               await scenarioPage.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
               {
                     ShowContent(null);
               });
               break;
            case "PrintSelection":
               await scenarioPage.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
               {
                     Scenario4PageRange page = (Scenario4PageRange)scenarioPage;
                     PageToPrint pageContent = (PageToPrint)page.PrintFrame.Content;
                     ShowContent(pageContent.TextContentBlock.SelectedText);
               });
               RemovePageRangeEdit(sender);
               break;
            default:
               await scenarioPage.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
               {
                     ShowContent(null);
               });
               RemovePageRangeEdit(sender);
               break;
         }

         Refresh();
   }
   else if (optionId == "PageRangeEdit")
   {
         IPrintOptionDetails pageRange = sender.Options[optionId];
         // Expected range format (p1,p2...)*, (p3-p9)* ...
         if (!Regex.IsMatch(pageRange.Value.ToString(), @"^\s*\d+\s*(\-\s*\d+\s*)?(\,\s*\d+\s*(\-\s*\d+\s*)?)*$"))
         {
            pageRange.ErrorText = "Invalid Page Range (eg: 1-3, 5)";
         }
         else
         {
            pageRange.ErrorText = string.Empty;
            try
            {
               GetPagesInRange(pageRange.Value.ToString());
               Refresh();
            }
            catch (InvalidPageException ipex)
            {
               pageRange.ErrorText = ipex.Message;
            }
         }
   }
}

Tip

 GetPagesInRange Lihat metode dalam sampel cetak UWP untuk detail tentang cara mengurai rentang halaman yang dimasukkan pengguna dalam kotak teks Rentang.

Pratinjau halaman terpilih

Cara Memformat konten aplikasi untuk pencetakan bergantung pada sifat aplikasi dan kontennya. Kelas pembantu cetak yang digunakan dalam sampel cetak UWP untuk memformat konten untuk pencetakan.

Saat mencetak subset halaman, ada beberapa cara untuk menampilkan konten dalam pratinjau cetak. Terlepas dari metode yang Anda pilih untuk menampilkan rentang halaman dalam pratinjau cetak, output yang dicetak hanya boleh berisi halaman yang dipilih.

  • Perlihatkan semua halaman dalam pratinjau cetak apakah rentang halaman ditentukan atau tidak, biarkan pengguna mengetahui halaman mana yang akan benar-benar dicetak.
  • Perlihatkan hanya halaman yang dipilih oleh rentang halaman pengguna dalam pratinjau cetak, memperbarui tampilan setiap kali pengguna mengubah rentang halaman.
  • Perlihatkan semua halaman dalam pratinjau cetak, tetapi berwarna abu-abu halaman yang tidak berada dalam rentang halaman yang dipilih oleh pengguna.