Getting Started with Code 39 Barcodes in C#
If you need a quick, reliable way to generate barcodes for a desktop or web application, Code 39 (often called “Code 3 of 9”) offers a straightforward solution. It’s one of the oldest symbologies, still widely supported by scanners, and it works well with a simple TrueType font that you can load into your application. Rather than pulling in a heavyweight third‑party component, you can use the font to render the barcode as text and then print or display it like any other string. The core idea is that each character in a Code 39 barcode is represented by a sequence of wide and narrow bars. The barcode font contains those sequences as glyphs. To make the barcode readable, you must surround the data with an asterisk (*) at the beginning and end – this marks the start and stop points for scanners. Without those asterisks, the symbol will not be recognized. The font also supports letters A–Z, digits 0–9, and a handful of punctuation symbols (space, dash, dot, slash, plus, dollar, percent, and hash), so you can encode a mix of alphanumeric data comfortably. To start, download the free Code 39 TrueType font from a reputable source. Once you have the .ttf file, install it on the development machine and reference it in your project’s resources. In a WinForms project, you can drag the font into the Resources folder, set its access modifier to “public”, and then create a System.Drawing.Font object that uses the font name. For example:Font barcodeFont = new Font("Code 39", 15f, FontStyle.Regular);</p>
public static string FormatBarcode(string data)</p>
<p>{</p>
<p>
if (!data.StartsWith("<em>") || !data.EndsWith("</em>"))</p>
<p>
{</p>
<p>
throw new ArgumentException("Barcode data must start and end with *");</p>
<p>
}</p>
<p>
return data;</p>
<p>}</p>
PrintPage event of a PrintDocument object, drawing the formatted string with the barcode font. By default, the PrintPreviewDialog will show the user a preview of what will be sent to the printer. If you want to keep testing costs low, you can wrap the preview logic inside a #if DEBUG directive so that the code only compiles in debug builds.
The human‑readable text – the string you entered – can be displayed underneath the barcode. Many printers and scanners read the text as a secondary source of information, which is handy for quick manual entry. However, including the text is optional; if you only care about the barcode, leave that part out. The code below shows how you can optionally print the text:
if (includeHumanReadable)</p>
<p>{</p>
<p>
e.Graphics.DrawString(data, new Font("Arial", 8), Brushes.Black,</p>
<p>
new PointF(50, 100));</p>
<p>}</p>
Printing and Previewing Your Barcode with Minimal Cost
Once you have the barcode string and font ready, the next challenge is to deliver it to a printer while keeping test costs down. The key is to separate preview and printing logic so that developers can see exactly what will be sent to the printer without incurring ink or paper usage. A common approach is to wrap the preview in a compile‑time directive, as mentioned earlier. When you compile in Release mode, the preview code is omitted and the application jumps straight to printing. Below is a typicalPrintDocument implementation that renders a Code 39 barcode. The class, named BarcodePrinter, encapsulates the formatting, drawing, and printer configuration steps. The PrintPage event handler receives a PrintPageEventArgs object, which gives you access to the Graphics context, printer margins, and page settings. The code ensures that the barcode fits within the printable area by checking the width of the rendered string and adjusting the font size if necessary.
public class BarcodePrinter</p>
<p>{</p>
<p>
private readonly string _barcodeText;</p>
<p>
private readonly Font _barcodeFont;</p>
<p>
private readonly bool _includeHumanReadable;</p>
<p>
public BarcodePrinter(string barcodeText, Font barcodeFont, bool includeHumanReadable = true)</p>
<p>
{</p>
<p>
_barcodeText = barcodeText;</p>
<p>
_barcodeFont = barcodeFont;</p>
<p>
_includeHumanReadable = includeHumanReadable;</p>
<p>
}</p>
<p>
public void Print()</p>
<p>
{</p>
<p>
using (PrintDocument doc = new PrintDocument())</p>
<p>
{</p>
<p>
doc.PrinterSettings.PrinterName = "YourPrinterName";</p>
<p>
doc.PrintPage += Doc_PrintPage;</p>
<p>
doc.Print();</p>
<p>
}</p>
<p>
}</p>
<p>
private void Doc_PrintPage(object sender, PrintPageEventArgs e)</p>
<p>
{</p>
<p>
float x = e.MarginBounds.Left + 10;</p>
<p>
float y = e.MarginBounds.Top + 10;</p>
<p>
// Draw the barcode</p>
<p>
e.Graphics.DrawString(_barcodeText, _barcodeFont, Brushes.Black,</p>
<p>
new PointF(x, y));</p>
<p>
// Optionally draw the human readable text beneath the barcode</p>
<p>
if (_includeHumanReadable)</p>
<p>
{</p>
<p>
Font textFont = new Font("Arial", 8f);</p>
<p>
e.Graphics.DrawString(_barcodeText, textFont, Brushes.Black,</p>
<p>
new PointF(x, y + _barcodeFont.GetHeight(e.Graphics) + 5));</p>
<p>
}</p>
<p>
}</p>
<p>}</p>
Print method initializes a PrintDocument, sets the printer name, hooks up the event, and triggers the print job. If you prefer to see a preview, replace doc.Print() with PrintPreviewDialog preview = new PrintPreviewDialog(); preview.Document = doc; preview.ShowDialog();. By controlling the printer name and page settings, you can direct output to a test printer or a virtual PDF printer during development.
A crucial detail that often trips up developers is the requirement for the asterisk delimiters. Many scanners silently ignore barcodes that lack the start/stop characters, which can lead to a false assumption that the barcode isn’t printing correctly. Always verify the barcode string in the preview window: it should look like ABC123 (including the asterisks). If the preview shows the string as normal text, double‑check that the font you’re using is indeed the Code 39 TrueType font and that the font name matches the one you pass to the Font constructor.
Testing cost savings are achieved in two ways. First, by using a #if DEBUG block around the preview logic, you never print to a physical printer while debugging, so you avoid ink or paper waste. Second, by using the PrintPreviewDialog you can adjust the layout, font size, and margins visually before committing to a print job. This approach reduces the number of failed prints, which is especially valuable in environments where printer uptime is critical.
Finally, remember that not all scanners read extremely wide barcodes. If your application needs to produce a barcode that spans the width of a page, test the physical dimensions on the target scanner. If the barcode is too wide, consider reducing the font size or printing on a narrower sheet. Conversely, if the barcode is too narrow, increase the font size until the scanner reliably reads the bars.
With this foundation in place, you can integrate Code 39 barcoding into any C# application, from small utility tools to large enterprise systems. The combination of a simple TrueType font and .NET’s printing APIs delivers a cost‑effective, reliable barcode solution that scales with your needs.





No comments yet. Be the first to comment!