silverlight4.0之条码循环打印

 

第一步将所需条码代码从网上下下来(网上好多),就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的出生吧。

posted @ 2010-12-20 21:15  一个人在北京  阅读(1479)  评论(2编辑  收藏  举报