Silverlight Barcode Software Project



The Project consists of two C# subprojects :

SilverlightBarcodeClassLibrary

This library is derived from the source code of the Code39 Barcode of the WPF Barcode Software project. The input and output properties, and methods of the Barcodes class are almost identitical.

Input Properties

BarcodeType - There are many types of barcodes used in real life. For example, those used in retail are different from those used in warehouses and logistics. Currently, the barcode library implements a simple but widely used barcode symbology known as Code 39. This barcode is also known as Code 3 of 9. This barcode accepts only upper case characters 'A' to >'Z', the numeric digits '0' to '9' and a few special characters. If you enter any other characters to the Data string, they will be ignored and filtered away.

The Code 39 barcode has the advantage of being simple, as each of the characters are represented by a pattern of 10 alternating white and black bars. However, because the algorithm does not include much compression, the resulting barcode out is not very dense. In other words, you get a rather long barcode for a short data string.

Data - This is the data to be encoded. For our WPF application, we have used "1234567" as the Data input string.

CheckDigit - Some barcodes specify that a check digit must be included into the barcode. The check digit is usually an additional character (or several characters) that is appended to the input Data string and encoded into the barcode. The CheckDigit helps the scanner to verify that the data that it reads is correct and complete. For the Code39 barcode, the CheckDigit is optional. You can specify Yes or No to include or exclude it.


Main Method

encode() - After you have specified the Input Properties, you can start letting the barcode class to create the black and white bars. This is done by calling the method encode(). When this is done, you can start retrieving the results using the Output Properties of the Barcodes class.


Output Properties

EncodedData - This is the result returned by the <code>Barcodes</code> after you have called the encode() method. The EncodedData returns a string in the form "twtwttwtttwtwttttwttwwttwtwttwttwtwttt". The "t" represents a thin bar, while the "w" represents a thick bar. A thick bar is usually 3 times the width of a thin bar. The way to interpret the result is that each character indicates alternating bar colors. For example for "twtw", the first "t" will be a thin black bar, the second "w" will be a thick white bar, the third "t" will be will be a thin black bar, and the fourth "w" will be a thick white bar. Our WPF application will use the string returned by EncodedData to draw a series of alternating black and white rectangles.

HumanText - This is a text that is usually placed below the barcode. The Human Text helps a person to read the content of the barcode when a scanner is not available. The HumanText is usually identical to the input Data, but that not always the case. Sometimes, the HumanText will be formatted with special Start/Stop characters, otherwise, it will include the extra CheckDigit. Our WPF application will use the string returned by HumanText to draw the Human Readable Text below the barcode.

SilverlightBarcodeApplication

The following is the layout of the control.

It consists of mainly a Canvas to hold the barcode and a TextBlock for the Human Readable Text. The default value of the
TextBlock is "1234" and it marks the location where the Human Readable Text of the barcode will be located. The barcode
is located exactly on top of the Human Readable Text. All the rest of the grid cells that surrounds the Canvas and TextBlock are considered quiet zones of the barcode -- they are deliberately left blank so that the scanner will not confuse anything in them with the actual barcode.

The following is the source code for Page.xaml. Set ShowGridLines to True to see the layout.

<UserControl x:Class="SilverlightBarcodeApplication.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="270" Height="100" Loaded="UserControl_Loaded">
<Grid x:Name="grdLayoutRoot" Background="White" Width="270" Height="100" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="10"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="10"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="250"></ColumnDefinition>
<ColumnDefinition Width="10"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Canvas x:Name="MyCanvas" Width="250" Height="50" Grid.Row="1" Grid.Column="1" />
<TextBlock x:Name="MyText" Width="250" Height="30" Text="1234" Grid.Row="2" Grid.Column="1" TextAlignment="Center" FontSize="16"/>
</Grid>
</UserControl>

The barcode is drawn in the UserControl_Loaded method when the Control is loaded.

The steps are rather straight forward. The control first uses the Barcode Library to return a string representing the bars of the barcode (known as the encodedData). From the encodedData, it is able to find the sum total of the number of thin bars that is able to fit into the Canvas width. (By the way, a thick bar is 3 times the width of a thin bar). This sum total is known as the encodedLength.

It then finds the width of the smallest bar in WPF coordinates (known as barWidth) by dividing the width of the Canvas by the encodedLength (the sum total of the number of thin bars).

float barWidth = (float)(this.MyCanvas.Width / encodedLength);

The barWidth is then used to draw the individual rectangles of the barcode. In this way, we are able to produce a barcode that fits into the Canvas exactly.


The following is the source code for the Usercontrol_Loaded method.

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Me.BarcodeSoftware.Barcode.Barcodes barcode = new Me.BarcodeSoftware.Barcode.Barcodes();
barcode.BarcodeType = Me.BarcodeSoftware.Barcode.Barcodes.BarcodeEnum.Code39;
barcode.Data = "123456";
barcode.encode();
string encodedData = barcode.EncodedData;
MyText.Text = barcode.HumanText;

int encodedLength = 0;
for (int x = 0; x < encodedData.Length; x++)
{
if (encodedData[x] == 't')
encodedLength++;
else if (encodedData[x] == 'w')
encodedLength = encodedLength + 3;
}

float barWidth = (float)(this.MyCanvas.Width / encodedLength);

if (barWidth < 1)
barWidth = 1;
float thickWidth = barWidth * 3;
double incrementWidth = 0;

int swing = 0;
for (int x = 0; x < encodedData.Length; x++)
{
Brush brush;
if (swing == 0)
brush = new SolidColorBrush(Colors.Black);
else
brush = new SolidColorBrush(Colors.White);

if (encodedData[x] == 't')
{
Rectangle r = new Rectangle();
r.Fill = brush;
r.Width = barWidth;
r.Height = this.MyCanvas.Height;
r.SetValue(Canvas.LeftProperty, incrementWidth);
r.SetValue(Canvas.TopProperty, 0.0);
MyCanvas.Children.Add(r);
incrementWidth = incrementWidth + ((barWidth));
}
else if (encodedData[x] == 'w')
{
Rectangle r = new Rectangle();
r.Fill = brush;
r.Width = 3 * barWidth;
r.Height = this.MyCanvas.Height;
r.SetValue(Canvas.LeftProperty, incrementWidth);
r.SetValue(Canvas.TopProperty, 0.0);
MyCanvas.Children.Add(r);
incrementWidth = incrementWidth + (3 * (barWidth));
}

if (swing == 0)
swing = 1;
else
swing = 0;
}
}
}




A further improvement on the source code is to override the OnRender function of the control.

For further updates on this project please visit
http://www.barcodesoftware.me

Last edited May 18, 2009 at 5:10 AM by barcodesoftware, version 5