条形码字体是一种简单的方法,但它们很难部署,因为客户可能需要在运行应用程序的每台机器上安装字体.这可能是不切实际的,特别是对于XBAP,Silverlight和WinPhone7部署.
在WPF中自己生成条形码非常容易.虽然它可以在纯XAML中完成,但我发现使用XAML和代码的混合最简单.
从带有角色的转换器开始,返回条形画笔和宽度:
public class BarcodeConverter : IValueConverter
{
public static readonly BarcodeConverter Instance = new BarcodeConverter();
Dictionary<char, string> _codes = new Dictionary<char, string>
{
{ '0', "nnnwwnwnn" },
{ '1', "wnnwnnnnw" },
{ '2', "nnwwnnnnw" },
// etc
{ 'A', "wnnnnwnnw" },
{ 'B', "nnwnnwnnw" },
// etc
};
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string code;
if(!_codes.TryGetValue((char)value, out code)) return null;
return
from i in Enumerable.Range(0, code.Length)
select new
{
color = i%2==0 ? Brushes.Black : Brushes.Transparent,
width = code[i]=='n' ? 5 : 10,
};
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
现在构建条形图的XAML是微不足道的:
<ItemsPanelTemplate x:Key="HorizontalPanel">
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="SingleBarTemplate">
<Rectangle Fill="{Binding color}" Width="{Binding width}" />
</DataTemplate>
<DataTemplate x:Key="SingleCodeTemplate">
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding}" /> <!-- Display character at bottom of code -->
<ItemsControl ItemsSource="{Binding Converter={x:Static my:BarcodeConverter.Instance}}"
ItemsPanel="{StaticResource HorizontalPanel}"
ItemTemplate="{StaticResource SingleBarTemplate}" />
</DockPanel>
</DataTemplate>
<DataTemplate x:Key="BarcodeTemplate">
<ItemsControl ItemsSource="{Binding}"
ItemsPanel="{StaticResource HorizontalPanel}"
ItemTemplate="{StaticResource SingleBarTemplate}"
Height="60" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
BarcodeTemplate可与ContentPresenter一起使用以显示任何字符串,例如:
<ContentPresenter Content="123456789"
ContentTemplate="{StaticResource BarcodeTemplate}" />
Run Code Online (Sandbox Code Playgroud)
要么
<ContentPresenter Content="{Binding UPCCode}"
ContentTemplate="{StaticResource BarcodeTemplate}" />
Run Code Online (Sandbox Code Playgroud)
我认为这个解决方案是在WPF中生成条形码的"最佳方法",因为:
以下是我最终得到的:
<Window x:Class="ScratchClient.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="655.85" Width="687"
xmlns:local="clr-namespace:ScratchClient">
<Window.Resources>
<local:BarcodeConverter x:Key="barcodeConverter"/>
<ItemsPanelTemplate x:Key="HorizontalPanel">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="SingleBarTemplate">
<Rectangle Fill="{Binding color}" Width="{Binding width}" />
</DataTemplate>
<DataTemplate x:Key="SingleCodeTemplate">
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding}" />
<ItemsControl ItemsSource="{Binding Converter={StaticResource barcodeConverter}}"
ItemsPanel="{StaticResource HorizontalPanel}"
ItemTemplate="{StaticResource SingleBarTemplate}" />
</DockPanel>
</DataTemplate>
<DataTemplate x:Key="BarcodeTemplate">
<ItemsControl ItemsSource="{Binding}"
ItemsPanel="{StaticResource HorizontalPanel}"
ItemTemplate="{StaticResource SingleCodeTemplate}"
Height="100" />
</DataTemplate>
</Window.Resources>
<Grid>
<ContentPresenter Name="barcode" Content="*WIKIPEDIA*" ContentTemplate="{StaticResource BarcodeTemplate}">
<ContentPresenter.RenderTransform>
<ScaleTransform ScaleX="2" ScaleY="2"></ScaleTransform>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Grid>
Run Code Online (Sandbox Code Playgroud)
public class BarcodeConverter : IValueConverter
{
//W Wide - Black
//N Narrow - Black
//w Wide - White
//n Narrow - White
#region code details
Dictionary<char, string> _codes = new Dictionary<char, string>
{
{'0',"NnNwWnWnN"},
{'1',"WnNwNnNnW"},
{'2',"NnWwNnNnW"},
{'3',"WnWwNnNnN"},
{'4',"NnNwWnNnW"},
{'5',"WnNwWnNnN"},
{'6',"NnWwWnNnN"},
{'7',"NnNwNnWnW"},
{'8',"WnNwNnWnN"},
{'9',"NnWwNnWnN"},
{'A',"WnNnNwNnW"},
{'B',"NnWnNwNnW"},
{'C',"WnWnNwNnN"},
{'D',"NnNnWwNnW"},
{'E',"WnNnWwNnN"},
{'F',"NnWnWwNnN"},
{'G',"NnNnNwWnW"},
{'H',"WnNnNwWnN"},
{'I',"NnWnNwWnN"},
{'J',"NnNnWwWnN"},
{'K',"WnNnNnNwW"},
{'L',"NnWnNnNwW"},
{'M',"WnWnNnNwN"},
{'N',"NnNnWnNwW"},
{'O',"WnNnWnNwN"},
{'P',"NnWnWnNwN"},
{'Q',"NnNnNnWwW"},
{'R',"WnNnNnWwN"},
{'S',"NnWnNnWwN"},
{'T',"NnNnWnWwN"},
{'U',"WwNnNnNnW"},
{'V',"NwWnNnNnW"},
{'W',"WwWnNnNnN"},
{'X',"NwNnWnNnW"},
{'Y',"WwNnWnNnN"},
{'Z',"NwWnWnNnN"},
{'-',"NwNnNnWnW"},
{'.',"WwNnNnWnN"},
{' ',"NwWnNnWnN"},
{'$',"NwNwNwNnN"},
{'/',"NwNwNnNwN"},
{'+',"NwNnNwNwN"},
{'%',"NnNwNwNwN"},
{'*',"NwNnWnWnN"},
};
#endregion
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string code;
int narrow = 1, wide = 3;
if (!_codes.TryGetValue((char)value, out code)) return null;
code += 'n';
var result = from i in Enumerable.Range(0, code.Length)
select new
{
color = (code[i] == 'W' || code[i] == 'N') ? Brushes.Black : Brushes.Transparent,
width = (code[i] == 'n' || code[i] == 'N') ? narrow : wide
};
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
我在github上创建了一个开源控件: https: //github.com/KevinPan/wpf-barcode,请尝试一下。
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
4784 次 |
| 最近记录: |