See Also
Other Platforms
Features
Buy Now
Online Help
Demo
Licensing

Back

How to print vector barcodes with WPF in a console app or Windows Service with C# or VB.NET

Prerequisites
In this guide you will learn how to print vector-based barcodes inside a Console App or Windows Service by using Neodynamic Barcode Professional for WPF.
Taking advantage on the printing features of WPF which is very powerful and easy to use, you can print barcode documents or labels in scenarios where the classic GDI+ (System.Drawing.Printing.PrintDocument class) is not supported like Windows Services. Although the source code in this guide is for Console Apps, you can easily port it to a Windows Service project.

This guide provides two printing scenarios. The first one is for printing a single page document featuring a Code 39 barcode while the second one is for printing a multipage document with a list of products. The products are in a XML file including id, name and price and a Code 128 barcode is generated for each product ID. Please note that although we have used simple linear barcodes Code 39 and Code 128 in this guide, you could use any of the barcode standards included in Barcode Professional for WPF like EAN-13, UPC-A, GS1-128, USPS Intelligent Mail Barcode as well as 2D symbologies like Data Matrix, QR Code, Aztec Code, PDF 417, etc. (More info about all supported barcode symbologies in Barcode Pro for WPF)

Please follow up these steps:
  • Download and install latest version of Neodynamic Barcode Professional for WPF
  • Open Visual Studio and create a new Console Application project
  • Add a new Class item to your project and name it SinglePageDocBarcode

    This class will print a single page with a Code 39 barcode encoding part of a random GUID. It is very straightforward but will provide you a basic code if you are in such printing scenario.



    Visual Basic .NET

    Imports System.Printing
    Imports System.Windows.Xps
    Imports System.Windows.Media
    Imports System.Globalization
    Imports System.Windows
    
    Public Class SinglePageDocBarcode
    
        Public Shared Sub Print()
            Dim server As New LocalPrintServer()
            Dim queue As PrintQueue = server.DefaultPrintQueue
            Dim ticket As PrintTicket = queue.DefaultPrintTicket
            Dim writer As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(queue)
            writer.Write(CreateVisual(ticket), ticket)
        End Sub
    
        Private Shared Function CreateVisual(ByVal ticket As PrintTicket) As Visual
            Dim width As Double = ticket.PageMediaSize.Width.Value
            Dim height As Double = ticket.PageMediaSize.Height.Value
            Const inch As Double = 96
    
            Dim visual As New DrawingVisual()
            Using dc As DrawingContext = visual.RenderOpen()
                'Draw a sample text
                dc.DrawText(New FormattedText("Sample Barcode in WPF", CultureInfo.InvariantCulture, FlowDirection.LeftToRight, New Typeface(New FontFamily("Arial"), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal), 14, Brushes.Black), New Point(0.5 * inch, 0.5 * inch))
    
                'Draw a barcode
                Dim bc As New Neodynamic.WPF.BarcodeBuilder()
                bc.BarcodeUnit = Neodynamic.WPF.BarcodeUnit.Inch
                bc.Symbology = Neodynamic.WPF.Symbology.Code39
                bc.Extended = True
                bc.AddChecksum = False
                bc.Code = Guid.NewGuid().ToString().ToUpper().Replace("-", "").Substring(0, 16)
                bc.BarWidth = 1 / inch
                bc.BarHeight = 0.75
                bc.QuietZone = New Thickness(0, 0.1, 0, 0.1)
                bc.FontSize = 12
                'locate the barcode drawing by using TranslateTransform
                dc.PushTransform(New TranslateTransform(0.5 * inch, inch))
    
                dc.DrawDrawing(bc.GetBarcodeDrawing())
    
            End Using
    
    
            Return visual
        End Function
    
    End Class
    


    C#

    using System;
    using System.Windows.Media;
    using System.Printing;
    using System.Windows;
    using System.Windows.Xps;
    using System.Globalization;
    
    namespace WPFBarcodePrintConsoleCS
    {
        class SinglePageDocBarcode
        {
    
            public static void Print()
            {
                LocalPrintServer server = new LocalPrintServer();
                PrintQueue queue = server.DefaultPrintQueue;
                PrintTicket ticket = queue.DefaultPrintTicket;
                XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(queue);
                writer.Write(CreateVisual(ticket), ticket);
            }
    
            private static Visual CreateVisual(PrintTicket ticket)
            {
                double width = ticket.PageMediaSize.Width.Value;
                double height = ticket.PageMediaSize.Height.Value;
                const double inch = 96;
    
                DrawingVisual visual = new DrawingVisual();
                using (DrawingContext dc = visual.RenderOpen())
                {
                    //Draw a sample text
                    dc.DrawText(new FormattedText("Sample Barcode in WPF",
                        CultureInfo.InvariantCulture,
                         FlowDirection.LeftToRight,
                         new Typeface(new FontFamily("Arial"), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal),
                         14,
                         Brushes.Black), new Point(0.5 * inch, 0.5 * inch));
    
                    //Draw a barcode
                    Neodynamic.WPF.BarcodeBuilder bc = new Neodynamic.WPF.BarcodeBuilder();
                    bc.BarcodeUnit = Neodynamic.WPF.BarcodeUnit.Inch;
                    bc.Symbology = Neodynamic.WPF.Symbology.Code39;
                    bc.Extended = true;
                    bc.AddChecksum = false;
                    bc.Code = Guid.NewGuid().ToString().ToUpper().Replace("-", "").Substring(0, 16);
                    bc.BarWidth = 1 / inch;
                    bc.BarHeight = 0.75;
                    bc.QuietZone = new Thickness(0, 0.1, 0, 0.1);
                    bc.FontSize = 12;
                    //locate the barcode drawing by using TranslateTransform
                    dc.PushTransform(new TranslateTransform(0.5 * inch, inch));
    
                    dc.DrawDrawing(bc.GetBarcodeDrawing());
    
                }
    
                return visual;
            }
    
        }
    }
    
  • Add a new Class item to your project and name it MultiPageDocBarcode

    This class is a bit more complex than the first one but easily to follow up. In this code the idea is to get Product info (ID, Name and Price) from an XML file and generated a multi page doc featuring a product list with a Code 128 barcode encoding the product ID. The sheet of paper is configured for US Letter size (8.5 inch x 11 inch) and will hold 10 product items per sheet. The class code has the following parts:

    • CreateProductItem method asks for product info and generate a Canvas object with a Code 128 vector drawing barcode generated by Barcode Professional for WPF encoding the product ID and 2 TextBlock objects for drawing the name and price of the specified product.
    • CreatePage method just creates a new FixedPage object with the US Letter size on demand based on the number of products to be printed.
    • CreateDocument method generates a FixedDocument (i.e. the multi page doc) creating as many as pages based on the data source i.e. a DataTable containing all product items got from the xml sample file.
    • Print method just open the xml sample file, get the product info into a DataTable and pass it to the CreateDocument which is then printed out using WPF Printing classes.




    Visual Basic .NET

    Imports System.Printing
    Imports System.Windows.Xps
    Imports System.Windows.Media
    Imports System.Globalization
    Imports System.Windows
    Imports System.Windows.Controls
    Imports System.Windows.Documents
    Imports System.Windows.Markup
    
    Public Class MultiPageDocBarcode
    
        Const INCH As Double = 96
    
        'US letter size in INCH
        Const PAPER_WIDTH As Double = 11
        Const PAPER_HEIGHT As Double = 8.5
        Const PAPER_MARGIN As Double = 0.5
    
        Const NUM_OF_PROD_PER_SHEET As Double = 10
    
    
        Private Shared Function CreateProductItem(ByVal id As String, ByVal name As String, ByVal price As String) As Canvas
            'Create a product canvas for placing text and barcode of the product
            Dim c As New Canvas()
            c.Width = (PAPER_WIDTH - 2 * PAPER_MARGIN) * INCH
            c.Height = (PAPER_HEIGHT / NUM_OF_PROD_PER_SHEET) * INCH
    
            'create barcode for product id
            Dim bc As New Neodynamic.WPF.BarcodeProfessional()
            bc.BarcodeUnit = Neodynamic.WPF.BarcodeUnit.Inch
            bc.Symbology = Neodynamic.WPF.Symbology.Code128
            bc.Code = id
            bc.BarWidth = 1 / INCH
            bc.BarHeight = 0.5
            bc.QuietZone = New Thickness(0, 0, 0, 0.1)
            bc.FontSize = 12
    
            'create textblocks for product info
            Dim txtProdName As New TextBlock()
            txtProdName.Text = name
            txtProdName.FontSize = 24
            txtProdName.SetValue(Canvas.LeftProperty, 2 * INCH)
    
            Dim txtProdPrice As New TextBlock()
            txtProdPrice.Text = "Retail Price: " + price
            txtProdPrice.FontSize = 20
            txtProdPrice.SetValue(Canvas.LeftProperty, 2 * INCH)
            txtProdPrice.SetValue(Canvas.TopProperty, 0.5 * INCH)
    
            'add elements to the canvas
            c.Children.Add(bc)
            c.Children.Add(txtProdName)
            c.Children.Add(txtProdPrice)
    
            Return c
        End Function
    
    
        Private Shared Function CreatePage() As FixedPage
            'Create new page
            Dim page As New FixedPage()
            'Set background
            page.Background = Brushes.White
            'Set page size (Letter size)
            page.Width = PAPER_WIDTH * INCH
            page.Height = PAPER_HEIGHT * INCH
            Return page
        End Function
    
    
        Private Shared Function CreateDocument(ByVal data As DataTable) As FixedDocument
    
            'Create new document
            Dim doc As New FixedDocument()
            'Set page size
            doc.DocumentPaginator.PageSize = New Size(PAPER_WIDTH * INCH, PAPER_HEIGHT * INCH)
    
            'Number of records
            Dim count As Double = data.Rows.Count
    
            If (count > 0) Then
    
                'Determine number of pages to generate
                Dim pageCount As Double = Math.Ceiling(count / NUM_OF_PROD_PER_SHEET)
    
                Dim dataIndex As Integer = 0
                Dim currentRow As Integer = 0
    
                Dim prodId As String
                Dim prodName As String
                Dim prodPrice As String
                Dim prodCanvas As Canvas
    
                Dim i As Integer = 0
                Dim j As Integer = 0
    
                For i = 0 To i < pageCount
    
                    'Create page
                    Dim page As New PageContent()
                    Dim fixedPage As FixedPage = CreatePage()
                    'Create labels
                    For j = 0 To j < NUM_OF_PROD_PER_SHEET
    
                        If (j Mod NUM_OF_PROD_PER_SHEET = 0) Then
                            currentRow = 0
                        Else
                            currentRow += 1
                        End If
    
                        If (dataIndex < count) Then
                            'Get data from DataTable
                            prodId = data.Rows(dataIndex)("ProdId").ToString
                            prodName = data.Rows(dataIndex)("ProdName").ToString
                            prodPrice = data.Rows(dataIndex)("ProdPrice").ToString
                            'Create individual product 'label'
                            prodCanvas = CreateProductItem(prodId, prodName, prodPrice)
    
                            'Set product label location
                            fixedPage.SetLeft(prodCanvas, PAPER_MARGIN * INCH)
                            fixedPage.SetTop(prodCanvas, PAPER_MARGIN * INCH + currentRow * prodCanvas.Height)
    
                            'Add label object to page
                            fixedPage.Children.Add(prodCanvas)
    
                            dataIndex += 1
                        End If
                    Next
    
                    'Invoke Measure(), Arrange() and UpdateLayout() for drawing
                    fixedPage.Measure(New Size(PAPER_WIDTH * 96, PAPER_HEIGHT * 96))
                    fixedPage.Arrange(New Rect(New Point(), New Size(PAPER_WIDTH * 96, PAPER_HEIGHT * 96)))
                    fixedPage.UpdateLayout()
    
                    DirectCast(page, IAddChild).AddChild(fixedPage)
    
                    doc.Pages.Add(page)
                Next
    
            End If
    
            Return doc
    
        End Function
    
    
        Public Shared Sub Print()
    
            'get data from xml file
            Dim xmlFile As String = "c:\temp\NorthwindProducts.xml"
            Dim ds As New DataSet()
            ds.ReadXml(xmlFile)
    
            'print
            Dim server As New LocalPrintServer()
            Dim queue As PrintQueue = server.DefaultPrintQueue
            Dim ticket As PrintTicket = queue.DefaultPrintTicket
            Dim writer As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(queue)
            writer.Write(CreateDocument(ds.Tables(0)), ticket)
    
        End Sub
    
    End Class
    


    C#

    using System;
    using System.Windows.Media;
    using System.Printing;
    using System.Windows;
    using System.Windows.Xps;
    using System.Globalization;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Data;
    using System.Windows.Markup;
    using System.IO;
    using System.Reflection;
    
    namespace WPFBarcodePrintConsoleCS
    {
        class MultiPageDocBarcode
        {
    
            const double INCH = 96;
    
            //US letter size in INCH
            const double PAPER_WIDTH = 11; 
            const double PAPER_HEIGHT = 8.5;
            const double PAPER_MARGIN = 0.5;
    
            const double NUM_OF_PROD_PER_SHEET = 10;
    
            private static Canvas CreateProductItem(string id, string name, string price)
            {
                //Create a product canvas for placing text and barcode of the product
                Canvas c = new Canvas();
                c.Width = (PAPER_WIDTH - 2 * PAPER_MARGIN) * INCH;
                c.Height = (PAPER_HEIGHT / NUM_OF_PROD_PER_SHEET) * INCH;
    
                //create barcode for product id
                Neodynamic.WPF.BarcodeProfessional bc = new Neodynamic.WPF.BarcodeProfessional();
                bc.BarcodeUnit = Neodynamic.WPF.BarcodeUnit.Inch;
                bc.Symbology = Neodynamic.WPF.Symbology.Code128;
                bc.Code = id;
                bc.BarWidth = 1 / INCH;
                bc.BarHeight = 0.5;
                bc.QuietZone = new Thickness(0, 0, 0, 0.1);
                bc.FontSize = 12;            
    
                //create textblocks for product info
                TextBlock txtProdName = new TextBlock();
                txtProdName.Text = name;
                txtProdName.FontSize = 24;
                txtProdName.SetValue(Canvas.LeftProperty, 2 * INCH);
    
                TextBlock txtProdPrice = new TextBlock();
                txtProdPrice.Text = "Retail Price: " + price;
                txtProdPrice.FontSize = 20;
                txtProdPrice.SetValue(Canvas.LeftProperty, 2 * INCH);
                txtProdPrice.SetValue(Canvas.TopProperty, 0.5 * INCH);
    
                //add elements to the canvas
                c.Children.Add(bc);
                c.Children.Add(txtProdName);
                c.Children.Add(txtProdPrice);
    
                return c;
            }
    
    
            private static FixedPage CreatePage()
            {
                //Create new page
                FixedPage page = new FixedPage();
                //Set background
                page.Background = Brushes.White;
                //Set page size (Letter size)
                page.Width = PAPER_WIDTH * INCH;
                page.Height = PAPER_HEIGHT * INCH;
                return page;
            }
    
    
            private static FixedDocument CreateDocument(DataTable data)
            {
                //Create new document
                FixedDocument doc = new FixedDocument();
                //Set page size
                doc.DocumentPaginator.PageSize = new Size(PAPER_WIDTH * INCH, PAPER_HEIGHT * INCH);
    
                //Number of records
                double count = (double)data.Rows.Count;
    
                if (count > 0)
                {
                    //Determine number of pages to generate
                    double pageCount = Math.Ceiling(count / NUM_OF_PROD_PER_SHEET);
    
                    int dataIndex = 0;
                    int currentRow = 0;
    
                    string prodId;
                    string prodName;
                    string prodPrice;
                    Canvas prodCanvas;
    
                    for (int i = 0; i < pageCount; i++)
                    {
                        //Create page
                        PageContent page = new PageContent();
                        FixedPage fixedPage = CreatePage();
                        //Create labels
                        for (int j = 0; j < NUM_OF_PROD_PER_SHEET; j++)
                        {
                            if (j % NUM_OF_PROD_PER_SHEET == 0)
                            {
                                currentRow = 0;
                            }
                            else
                            {
                                currentRow++;
                            }
    
    
                            if (dataIndex < count)
                            {
                                //Get data from DataTable
                                prodId = (string)data.Rows[dataIndex]["ProdId"];
                                prodName = (string)data.Rows[dataIndex]["ProdName"];
                                prodPrice = (string)data.Rows[dataIndex]["ProdPrice"];
                                //Create individual product 'label'
                                prodCanvas = CreateProductItem(prodId, prodName, prodPrice);
    
                                //Set product label location
                                FixedPage.SetLeft(prodCanvas, PAPER_MARGIN * INCH);
                                FixedPage.SetTop(prodCanvas, PAPER_MARGIN * INCH + currentRow * prodCanvas.Height);
    
                                //Add label object to page
                                fixedPage.Children.Add(prodCanvas);
    
                                dataIndex++;
                            }
                        }
    
                        //Invoke Measure(), Arrange() and UpdateLayout() for drawing
                        fixedPage.Measure(new Size(PAPER_WIDTH * 96, PAPER_HEIGHT * 96));
                        fixedPage.Arrange(new Rect(new Point(), new Size(PAPER_WIDTH * 96, PAPER_HEIGHT * 96)));
                        fixedPage.UpdateLayout();
                        
                        ((IAddChild)page).AddChild(fixedPage);
    
                        doc.Pages.Add(page);
                    }
                }
    
                return doc;
            }
    
    
            public static void Print()
            {
                //get data from xml file
                string xmlFile = @"c:\temp\NorthwindProducts.xml";
                DataSet ds = new DataSet();
                ds.ReadXml(xmlFile);
                
                //print
                LocalPrintServer server = new LocalPrintServer();
                PrintQueue queue = server.DefaultPrintQueue;
                PrintTicket ticket = queue.DefaultPrintTicket;
                XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(queue);
                writer.Write(CreateDocument(ds.Tables[0]), ticket);
            }
    
        }
    
    }
    
    
  • Finally, open the created Module1.vb OR Program.cs class and paste the following code. This is a simple menu allowing the user to select which printing scenario to process.

    Visual Basic .NET

    Module Module1
    
        Sub Main()
    
            Dim done As Boolean = False
    
            Do
                Console.WriteLine("Neodynamic Barcode Pro for WPF")
                Console.WriteLine("WPF Barcode Printing in Console or Windows Services")
                Console.WriteLine("===================================================\n\n")
                Console.WriteLine("Select one of the following:\n")
                Console.WriteLine("1 -> For printing a single page with a barcode")
                Console.WriteLine("2 -> For printing a multipage doc with barcodes\n")
                Console.Write("Enter Your selection (0 to exit): ")
                Dim userSelect As String = Console.ReadLine()
                Dim iSel As Integer
    
                Try
                    iSel = Integer.Parse(userSelect)
                Catch
                    Console.Clear()
                    Continue Do
                End Try
    
                If iSel = 0 Then
                    done = True
                ElseIf iSel = 1 Then
                    Console.WriteLine("Printing a single page with a barcode...")
                    SinglePageDocBarcode.Print()
                ElseIf iSel = 2 Then
                    Console.WriteLine("Printing a multipage doc with barcodes...")
                    MultiPageDocBarcode.Print()
                Else
                    Console.Clear()
                    Continue Do
                End If
    
                Console.WriteLine()
            Loop While Not (done)
    
        End Sub
    
    End Module
    


    C#

    using System;
    
    namespace WPFBarcodePrintConsoleCS
    {
        class Program
        {
            [STAThread]
            static void Main(string[] args)
            {
    
                bool done = false;
    
                do
                {
                    Console.WriteLine("Neodynamic Barcode Pro for WPF");
                    Console.WriteLine("WPF Barcode Printing in Console or Windows Services");
                    Console.WriteLine("===================================================\n\n");
                    Console.WriteLine("Select one of the following:\n");
                    Console.WriteLine("1 -> For printing a single page with a barcode");
                    Console.WriteLine("2 -> For printing a multipage doc with barcodes\n");
                    Console.Write("Enter Your selection (0 to exit): ");
                    string userSelect = Console.ReadLine();
                    int iSel;
                    try
                    {
                        iSel = int.Parse(userSelect);
                    }
                    catch
                    {
                        Console.Clear();
                        continue;
                    }
                    switch (iSel)
                    {
                        case 0:
                            done = true;
                            break;
                        case 1:
                            Console.WriteLine("Printing a single page with a barcode...");
                            SinglePageDocBarcode.Print();
                            break;
                        case 2:
                            Console.WriteLine("Printing a multipage doc with barcodes...");
                            MultiPageDocBarcode.Print();
                            break;    
                        default:
                            Console.Clear();
                            continue;                        
                    }
                    Console.WriteLine();
                } while (!done);
                
            }
            
        }
    }
    
  • That's it. Run the project and test it.
Sample Files Download
Here are the VB.NET and C# versions of this sample. Please download the zip file and extract it.
Remember to download and install Barcode Professional for WPF in order to reproduce this sample demo.
If you need more information or assistance, please contact our .
 Copyright © 2003 - 2012 Neodynamic S.R.L. All rights reserved.