Neodynamic Barcode Professional 4.0 for WPF (or greater)
Microsoft .NET Framework 3.5 (or greater)
Microsoft Visual Studio 2010 or Visual Basic 2010 Express or Visual C# 2010 Express
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 Professional for WPF)
Please follow up these steps:
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
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;
}
}
}
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
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);
}
}
}
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
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);
}
}
}
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.
We provide best-in-class customer service and support directly from members of our dev team! If we are available when you contact us, you will get a response in few minutes; otherwise the maximum turnaround is 24hs in most cases.