Virtual Developer Workshop: Containerized Development with Docker
Hello and welcome to my article. Today, I will demonstrate how simple, yet complicated, printing is inside your Windows 8.1 apps.
Start Visual Studio 2013 and create a new VB Windows Store application. If you are uncertain on just how to get started, feel free to read the following articles:
- 25 Tools You Can Use for Windows 8 Store App Development
- How to Make Toast Notifications in your Windows Store Application with VB
- Windows 8/8.1 ApplicationDataContainers and VB
- A button named btnPrint with a Content value of Print Charms
- A button named btnPrintInApp with a Content value of Print in App
Before I jump in with the code for these buttons, I must first explain how to add a new PrintPage to your application. This PrintPage can be used as a print preview for your application. Add a new Page now by following the next steps:
- Click Project.
- Click Add New Item.
- Click Blank Page.
- Click Add after you have given it a descriptive name, such as PrintPage.xaml.
Add the following Namespaces to this page:
Imports System Imports Windows.Graphics.Printing Imports Windows.UI.Xaml.Printing
These namespaces help with printing and print settings. Add the following fields to your page:
Protected Const MarginLeft As Double = 0.075 Protected Const MarginTop As Double = 0.03
At first glance, you can already figure out what each object's purpose would be. That is why it is so important to properly name your objects. The first two objects deal with the page's left and top margins respectively.
Add the following to your printing page:
Protected Sub PreparePrintContent() End Sub Protected Read-Only Property Printing Root() As Canvas Get Return TryCast(FindName("_printingRoot"), Canvas) End Get End Property
Here we allow this document to be printed and specify where to begin.
Add the following Imports to your page:
Imports Windows.Graphics.Printing Imports Windows.UI.Xaml.Printing
There are two Imports. The first import is to import the built-in Windows Printing element. The next one is specifically for Windows Store apps. Add the following fields to your page:
Private Registered As Boolean = False Private pp As New PrintPage Protected printDoc As PrintDocument = Nothing Protected printDocSource As IPrintDocumentSource = Nothing Friend printPreviewPages As List(Of UIElement) = Nothing Protected firstPage As FrameworkElement
These objects identify the printable document, its source, as well as the print preview. A very important object to talk about is the first object, Registered. This variable will either tell us if a document that is registered is to be printed or not. A document must be registered for printing; otherwise, it will not print. You must also remember to add the necessary application permissions to permit printing capabilities. If you are uncertain on how to do that, refer to the articles I listed at the beginning of this article.
In App Printing
Not much to be added here. Add this piece of code to your page:
Private Async Sub btnPrintInApp_Click(sender As Object, e As RoutedEventArgs) Handles btnPrintInApp.Click Await PrintManager.ShowPrintUIAsync() End Sub
As simple as that. This makes use of the PrintManager object inside the Windows.Graphics.Printing Namespace. This simply shows the Printing options.
Add the following code:
Protected Sub PreparePrintContent() End Sub Protected Sub RegisterForPrinting() printDoc = New PrintDocument() printDocSource = printDoc.DocumentSource AddHandler printDoc.Paginate, AddressOf CreatePrintPreviewPages AddHandler printDoc.GetPreviewPage, AddressOf GetPrintPreviewPage Dim printMngr As PrintManager = PrintManager.GetForCurrentView() AddHandler printMngr.PrintTaskRequested, AddressOf PrintTaskRequested PreparePrintContent() End Sub Protected Sub UnregisterForPrinting() If printDoc Is Nothing Then Return End If RemoveHandler printDoc.Paginate, AddressOf CreatePrintPreviewPages RemoveHandler printDoc.GetPreviewPage, AddressOf GetPrintPreviewPage Dim printMngr As PrintManager = PrintManager.GetForCurrentView() RemoveHandler printMngr.PrintTaskRequested, AddressOf PrintTaskRequested End Sub
These subs take care of registering your document to be printed, as well as unregistering it. They also allow us to set up our preview page through a call to GetPreviewPages and CreatePreviewPage, as shown next:
Protected Sub GetPrintPreviewPage(ByVal sender As Object, ByVal e As GetPreviewPageEventArgs) Dim printDoc As PrintDocument = CType(sender, PrintDocument) printDoc.SetPreviewPage(e.PageNumber, printPreviewPages(e.PageNumber - 1)) End Sub Protected Event pagesCreated As EventHandler Protected Sub CreatePrintPreviewPages(ByVal sender As Object, ByVal e As PaginateEventArgs) printPreviewPages.Clear() Dim printingOptions As PrintTaskOptions = (CType(e.PrintTaskOptions, PrintTaskOptions)) Dim pageDescription As PrintPageDescription = printingOptions.GetPageDescription(0) If pagesCreatedEvent IsNot Nothing Then pagesCreatedEvent.Invoke(printPreviewPages, Nothing) End If Dim printDoc As PrintDocument = CType(sender, PrintDocument) printDoc.SetPreviewPageCount(printPreviewPages.Count, PreviewPageCountType.Intermediate) End Sub
Add the PrintTaskRequested event:
Protected Sub PrintTaskRequested(ByVal sender As PrintManager, ByVal e As PrintTaskRequestedEventArgs) Dim printingTask As PrintTask = Nothing printingTask = e.Request.CreatePrintTask("Printing Example", Sub(sourceRequestedArgs) Dim displayedOptions As IList(Of String) = printingTask.Options.DisplayedOptions displayedOptions.Clear() displayedOptions.Add(Windows.Graphics.Printing.StandardPrintTaskOptions.Copies) displayedOptions.Add(Windows.Graphics.Printing.StandardPrintTaskOptions.Orientation) displayedOptions.Add(Windows.Graphics.Printing.StandardPrintTaskOptions.MediaSize) displayedOptions.Add(Windows.Graphics.Printing.StandardPrintTaskOptions.Collation) displayedOptions.Add(Windows.Graphics.Printing.StandardPrintTaskOptions.Duplex) printingTask.Options.MediaSize = PrintMediaSize.NorthAmericaLegal AddHandler printingTask.Completed, Async Sub(s, args) If args.Completion = PrintTaskCompletion.Failed Then Await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, Sub() tb1.Text = "Failed to print.") End If End Sub sourceRequestedArgs.SetSource(printDocSource) End Sub) End Sub
Now, we have much more flexibility when trying to print or preview a document. Add the remaining Print button's code:
Private Sub btnPrint_Click(sender As Object, e As RoutedEventArgs) Handles btnPrint.Click Dim clickedButton As Button = TryCast(sender, Button) ' Check to see if the application is registered for printing If Registered Then UnregisterForPrinting() clickedButton.Content = "Register" Else RegisterForPrinting() clickedButton.Content = "Unregister" End If Registered = Not Registered End Sub
I hope you have learned from today's article and that you can put this new knowledge to safe use. Until next time, this is me signing off.