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