在现代软件开发中,条形码技术被广泛应用于零售、物流和仓库管理等多个领域。MicrosoftSilverlight技术提供了一种在浏览器中运行富互联网应用程序(RIA)的方法。本文将介绍如何利用Silverlight技术构建一个条形码软件应用,该应用可以在任何支持Silverlight的浏览器中运行。要编译源文件,至少需要Visual Web Developer 2008 Express Edition。
本项目包含两个C#子项目:
这个类库是基于WPF条形码软件项目的Code39条形码源代码派生的。Barcodes类的输入和输出属性以及方法几乎相同。为方便起见,下面将重述这些属性和方法:
条形码类型(BarcodeType):现实世界中使用的条形码类型众多,例如零售业使用的与物流和仓储使用的条形码不同。目前,条形码库实现了一种简单但广泛使用的条形码符号,称为Code 39。这种条形码也被称为Code 3 of 9。它只接受大写字母'A'到'Z'、数字'0'到'9'和一些特殊字符。如果输入的Data字符串包含其他字符,它们将被忽略并过滤掉。
数据(Data):这是要编码的数据。在WPF应用程序中,使用了"1234567"作为Data输入字符串。
校验数字(CheckDigit):一些条形码规定必须在条形码中包含一个校验数字。校验数字通常是附加到输入Data字符串的额外字符(或几个字符),并编码到条形码中。校验数字有助于扫描器验证它读取的数据是正确和完整的。对于Code39条形码,校验数字是可选的。可以指定"Yes"或"No"来包含或排除它。
编码(encode()):在指定了输入属性之后,可以开始让条形码类创建黑白条。这是通过调用方法encode()来完成的。完成后,可以开始使用Barcodes类的输出属性检索结果。
编码数据(EncodedData):这是在调用encode()方法后Barcodes返回的结果。EncodedData以字符串形式返回,如"twtwttwtttwtwttttwttwwttwtwttwttwtwttt"。"t"代表细条,而"w"代表宽条。宽条通常是细条宽度的三倍。
结果的解释方式是,每个字符表示交替的条颜色。例如,对于"twtw",第一个"t"将是一个细黑条,第二个"w"将是一个宽白条,第三个"t"将是一个细黑条,第四个"w"将是一个宽白条。WPF应用程序将使用EncodedData返回的字符串来绘制一系列交替的黑白矩形。
人类文本(HumanText):这通常是放在条形码下方的文本。HumanText帮助人们在没有扫描器的情况下读取条形码的内容。HumanText通常与输入Data相同,但并不总是这样。有时,HumanText会用特殊的开始/停止"*"字符格式化;否则,它将包括额外的CheckDigit。WPF应用程序将使用HumanText返回的字符串在条形码下方绘制人类可读的文本。
控件的布局主要由一个Canvas组成,用于容纳条形码,以及一个TextBlock用于人类可读的文本。TextBlock的默认值为"1234",它标记了条形码的人类可读文本将被放置的位置。条形码正好位于人类可读文本的正上方。围绕Canvas和TextBlock的所有其他网格单元格都被认为是条形码的安静区域——它们被故意留空,以便扫描器不会将其中的任何内容与实际的条形码混淆。
以下是Page.xaml的源代码。将ShowGridLines设置为True以查看布局:
条形码是在控件加载时在UserControl_Loaded方法中绘制的。步骤相当直接。控件首先使用条形码库返回代表条形码条的字符串(称为encodedData)。从encodedData中,它可以找到能够适应Canvas宽度的细条总数。(顺便说一下,宽条是细条宽度的三倍)。这个总数称为encodedLength。
然后它找到WPF坐标中最小条的宽度(称为barWidth),方法是将Canvas的宽度除以encodedLength(细条的总数)。
float barWidth = (float)(this.MyCanvas.Width / encodedLength);
然后使用barWidth来绘制条形码的各个矩形。通过这种方式,能够产生一个正好适合Canvas的条形码。
以下是Usercontrol_Loaded方法的源代码:
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;
}
}