第一步将所需条码代码从网上下下来(网上好多),就code39举例:
BarCode.cs文件:
using System;
using System.Collections.Generic;
using System.Text;
namespace EamManager.BarCode
{
public class Barcodes
{
public enum YesNoEnum
{
Yes,
No
}
public enum BarcodeEnum
{
Code39
}
public string Data
{
get
{
return data;
}
set
{
data = value;
}
}
private string data;
public BarcodeEnum BarcodeType
{
get
{
return barcodeType;
}
set
{
barcodeType = value;
}
}
private BarcodeEnum barcodeType;
public YesNoEnum CheckDigit
{
get
{
return checkDigit;
}
set
{
checkDigit = value;
}
}
private YesNoEnum checkDigit;
public string HumanText
{
get
{
return humanText;
}
set
{
humanText = value;
}
}
private string humanText;
public string EncodedData
{
get
{
return encodedData;
}
set
{
encodedData = value;
}
}
private string encodedData;
public void encode()
{
int check = 0 ;
if ( checkDigit == Barcodes.YesNoEnum.Yes )
check = 1 ;
if ( barcodeType == BarcodeEnum.Code39 )
{
Code39 barcode = new Code39();
encodedData = barcode.encode( data, check );
humanText = barcode.getHumanText();
}
}
}
}
Code39.cs文件:
using System;
using System.Collections.Generic;
using System.Text;
namespace EamManager.BarCode
{
public class Code39
{
// w - wide
// t - thin
// Start the drawing with black, white, black, white......
public string encode( string data, int chk )
{
string fontOutput = mcode( data, chk );
string output = "" ;
string pattern = "" ;
for ( int x = 0 ; x < fontOutput.Length; x ++ )
{
switch ( fontOutput[ x ] )
{
case ' 1 ' :
pattern = " wttwttttwt " ;
break ;
case ' 2 ' :
pattern = " ttwwttttwt " ;
break ;
case ' 3 ' :
pattern = " wtwwtttttt " ;
break ;
case ' 4 ' :
pattern = " tttwwtttwt " ;
break ;
case ' 5 ' :
pattern = " wttwwttttt " ;
break ;
case ' 6 ' :
pattern = " ttwwwttttt " ;
break ;
case ' 7 ' :
pattern = " tttwttwtwt " ;
break ;
case ' 8 ' :
pattern = " wttwttwttt " ;
break ;
case ' 9 ' :
pattern = " ttwwttwttt " ;
break ;
case ' 0 ' :
pattern = " tttwwtwttt " ;
break ;
case ' A ' :
pattern = " wttttwttwt " ;
break ;
case ' B ' :
pattern = " ttwttwttwt " ;
break ;
case ' C ' :
pattern = " wtwttwtttt " ;
break ;
case ' D ' :
pattern = " ttttwwttwt " ;
break ;
case ' E ' :
pattern = " wtttwwtttt " ;
break ;
case ' F ' :
pattern = " ttwtwwtttt " ;
break ;
case ' G ' :
pattern = " tttttwwtwt " ;
break ;
case ' H ' :
pattern = " wttttwwttt " ;
break ;
case ' I ' :
pattern = " ttwttwwttt " ;
break ;
case ' J ' :
pattern = " ttttwwwttt " ;
break ;
case ' K ' :
pattern = " wttttttwwt " ;
break ;
case ' L ' :
pattern = " ttwttttwwt " ;
break ;
case ' M ' :
pattern = " wtwttttwtt " ;
break ;
case ' N ' :
pattern = " ttttwttwwt " ;
break ;
case ' O ' :
pattern = " wtttwttwtt " ;
break ;
case ' P ' :
pattern = " ttwtwttwtt " ;
break ;
case ' Q ' :
pattern = " ttttttwwwt " ;
break ;
case ' R ' :
pattern = " wtttttwwtt " ;
break ;
case ' S ' :
pattern = " ttwtttwwtt " ;
break ;
case ' T ' :
pattern = " ttttwtwwtt " ;
break ;
case ' U ' :
pattern = " wwttttttwt " ;
break ;
case ' V ' :
pattern = " twwtttttwt " ;
break ;
case ' W ' :
pattern = " wwwttttttt " ;
break ;
case ' X ' :
pattern = " twttwtttwt " ;
break ;
case ' Y ' :
pattern = " wwttwttttt " ;
break ;
case ' Z ' :
pattern = " twwtwttttt " ;
break ;
case ' - ' :
pattern = " twttttwtwt " ;
break ;
case ' . ' :
pattern = " wwttttwttt " ;
break ;
case ' ' :
pattern = " twwtttwttt " ;
break ;
case ' * ' :
pattern = " twttwtwttt " ;
break ;
case ' $ ' :
pattern = " twtwtwtttt " ;
break ;
case ' / ' :
pattern = " twtwtttwtt " ;
break ;
case ' + ' :
pattern = " twtttwtwtt " ;
break ;
case ' % ' :
pattern = " tttwtwtwtt " ;
break ;
}
output = output.Insert( output.Length, pattern );
}
return output;
}
private string humanText;
static char [] CODE39MAP = { ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' , ' 8 ' , ' 9 ' ,
' A ' , ' B ' , ' C ' , ' D ' , ' E ' , ' F ' , ' G ' , ' H ' , ' I ' , ' J ' ,
' K ' , ' L ' , ' M ' , ' N ' , ' O ' , ' P ' , ' Q ' , ' R ' , ' S ' , ' T ' ,
' U ' , ' V ' , ' W ' , ' X ' , ' Y ' , ' Z ' , ' - ' , ' . ' , ' ' , ' $ ' ,
' / ' , ' + ' , ' % ' };
private string mcode( string data, int chk )
{
string cd = "" , result = "" ;
string filtereddata = filterInput( data );
int filteredlength = filtereddata.Length;
if ( chk == 1 )
{
if ( filteredlength > 254 )
filtereddata = filtereddata.Remove( 254 , filteredlength - 254 );
cd = generateCheckDigit( filtereddata );
}
else
{
if ( filteredlength > 255 )
filtereddata = filtereddata.Remove( 255 , filteredlength - 255 );
}
result = " * " + filtereddata + cd + " * " ;
humanText = result;
return result;
}
public string getHumanText()
{
return humanText;
}
string generateCheckDigit( string data )
{
int datalength = 0 ;
int sum = 0 ;
int result = - 1 ;
string strResult = "" ;
char barcodechar;
datalength = data.Length;
for ( int x = 0 ; x < datalength; x ++ )
{
barcodechar = data[ x ];
sum = sum + getCode39Value( barcodechar );
}
result = sum % 43 ;
strResult = getCode39Character( result ).ToString();
return strResult;
}
char getCode39Character( int inputdecimal )
{
return CODE39MAP[ inputdecimal ];
}
int getCode39Value( char inputchar )
{
for ( int x = 0 ; x < 43 ; x ++ )
{
if ( CODE39MAP[ x ] == inputchar )
return x;
}
return - 1 ;
}
string filterInput( string data )
{
string result = "" ;
int datalength = data.Length;
for ( int x = 0 ; x < datalength; x ++ )
{
char barcodechar = data[ x ];
if ( getCode39Value( barcodechar ) != - 1 )
result = result.Insert( result.Length, barcodechar.ToString() );
}
return result;
}
}
}
第二部:设计条码显示界面
新建silverlight用户控件具体如下:
Code.xaml文件:
< UserControl x:Class = " EamManager.BarCode.Code "
xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml "
xmlns:d = " http://schemas.microsoft.com/expression/blend/2008 " xmlns:controls = " clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls "
xmlns:mc = " http://schemas.openxmlformats.org/markup-compatibility/2006 "
mc:Ignorable = " d "
d:DesignHeight = " 300 " d:DesignWidth = " 400 " IsEnabled = " True " BorderThickness = " 0 " HorizontalAlignment = " Center " VerticalAlignment = " Center " >
< Grid x:Name = " gr " >
< Grid x:Name = " grdLayoutRoot " Background = " White " Width = " 270 " Height = " 150 " ShowGridLines = " False " >
< Grid.RowDefinitions >
< RowDefinition Height = " 10 " ></ RowDefinition >
< RowDefinition Height = " 29 " />
< RowDefinition Height = " 40 " ></ RowDefinition >
< RowDefinition Height = " 30 " ></ RowDefinition >
< RowDefinition Height = " 40 " ></ RowDefinition >
< RowDefinition Height = " * " />
</ Grid.RowDefinitions >
< Grid.ColumnDefinitions >
< ColumnDefinition Width = " 10 " ></ ColumnDefinition >
< ColumnDefinition Width = " 137 " ></ ColumnDefinition >
< ColumnDefinition Width = " 113 " />
< ColumnDefinition Width = " 10 " ></ ColumnDefinition >
</ Grid.ColumnDefinitions >
< Canvas x:Name = " MyCanvas " Width = " 250 " Height = " 40 " Grid.Row = " 3 " Grid.Column = " 1 " Grid.ColumnSpan = " 2 " />
< TextBlock x:Name = " MyText " Height = " 30 " Text = " 1234 " Grid.Row = " 4 " Grid.Column = " 1 " TextAlignment = " Center " FontSize = " 13 " Margin = " 0,0,2,0 " />
< StackPanel Grid.Column = " 1 " Grid.Row = " 1 " Orientation = " Horizontal " HorizontalAlignment = " Center " Grid.ColumnSpan = " 2 " Margin = " 22,0 " >
< Image Height = " 26 " Name = " image1 " Stretch = " Fill " VerticalAlignment = " Center " Width = " 28 " Source = " /EamManager;component/Images/logo1.png " />
< TextBlock Height = " 26 " Name = " textBlock1 " Text = " xxx学院资产 " VerticalAlignment = " Center " FontSize = " 14 " />
</ StackPanel >
</ Grid >
</ Grid >
</ UserControl >
Code.xaml.cs文件:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace EamManager.BarCode
{
public partial class Code : UserControl
{
public Code( string codedata)
{
InitializeComponent();
Out_Code(codedata);
}
public void Out_Code( string codedata)
{
// 条码输出
Barcodes barcode = new Barcodes();
barcode.BarcodeType = Barcodes.BarcodeEnum.Code39;
barcode.Data = codedata;
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 ;
}
}
}
}
第三步:封装打印方法BarcodePrint.cs文件:
public void Print(UIElement source, string documentName)
{
var doc = new PrintDocument();
var offsetY = 0d;
var totalHeight = 0d;
var canvas = new Canvas();
canvas.Children.Add(source);
doc.EndPrint += (s, e) =>
{
if (e.Error == null )
{
MessageBox.Show( " 打印成功 " );
}
else
{
MessageBox.Show(e.Error.Message);
}
};
doc.PrintPage += (s, e) =>
{
e.PageVisual = canvas;
canvas.Margin = new Thickness( 50 );
if (totalHeight == 0 )
{
totalHeight = source.DesiredSize.Height;
}
Canvas.SetTop(source, - offsetY);
offsetY += e.PrintableArea.Height;
e.HasMorePages = offsetY <= totalHeight;
};
doc.Print(documentName);
}
第四步:准备一个窗体PrintWindow.xaml里面代码如下(其实就是只有一个stackpanel控件就好了):
< controls:ChildWindow x:Class = " EamManager.PrintWindow "
xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml " xmlns:controls = " clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls "
xmlns:d = " http://schemas.microsoft.com/expression/blend/2008 "
xmlns:mc = " http://schemas.openxmlformats.org/markup-compatibility/2006 "
mc:Ignorable = " d "
d:DesignHeight = " 300 " d:DesignWidth = " 400 " xmlns:sdk = " http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk " >
< StackPanel x:Name = " LayoutRoot " >
</ StackPanel >
</ controls:ChildWindow >
第五步:使用以上的工作,找到打印事件,在里面写:
PrintWindow pw = new PrintWindow();
foreach (DeviceInfo item in DG_Result.ItemsSource)
{
BarCode.Code code = new BarCode.Code(item.BarCode);
pw.LayoutRoot.Children.Add(code);
}
// DG_Result是datagrid,这里可是其他数据源集合,DeviceInfo为产品类(自定义),BarCode是DeviceInfo的编号
BarcodePrint.Print(pw, "设备条码 " );
通过以上步骤就实现了条码循环打印功能。
总结:
所遇问题:
silverlight4.0中printdocument类还不够完善,无法实现多次实例化,也就无法实现多次调用。
silverlight4.0采用安全机制,导致无法调用win32 api打印类(可能通过wcf可以,没试过,不过那样不合理)
解决办法:
将要打印的条码控件封装到usercontrol,然后在打印时将所有的usercontrol放到一个页面,然后控制打印时的页面大小,以便实现循环打印。
其实打印的是一个页面,只不过因为页面太大导致效果如同循环打印一般。
当然这种办法虽然实现此功能但是有很大的限制,比如:打印次数以及性能等。一同期待silverlight5.0的出生吧。