wpf中的条形码生成器

Dha*_*las 3 wpf prism

在wpf中以各种类型生成条形码的最佳方法是什么.

Ray*_*rns 6

条形码字体是一种简单的方法,但它们很难部署,因为客户可能需要在运行应用程序的每台机器上安装字体.这可能是不切实际的,特别是对于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中生成条形码的"最佳方法",因为:

  1. 它简单而独立,
  2. 它不依赖于计算机上安装的字体,而且
  3. 它可以在任何WPF或Silverlight实现上运行.


Pho*_*son 5

以下是我最终得到的:

<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,请尝试一下。

希望这可以帮助。