使用WPF动态生成Code 39条形码

最近在看些条形码方面相关的资料,而如果只是看的话,效果似乎并不怎么好,所以决定动手做点Demo,以增强对相关知识的记忆。

这里是一个我编写的使用WPF生成Code 39的例子,Code 39的编码很简单,故而第一次先用它做为尝试。

标准的Code 39只支持43个字符,0~9,A~Z,-,.,$, /, +, %以及空格。除此之外,*用于起始和终止符号。而通过使用两个编码符的扩展,则可以支持所有的Acsii码字符。相关知识可以在维基百科上找到。

由于是WPF,Demo分为两个文件,xaml文件包含界面布局相关的代码:

<Window x:Class="Code39Demo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <TextBox Name="Textbox1" VerticalContentAlignment="Center" TextChanged="Textbox1_TextChanged"></TextBox>
        <Canvas Name="Canvas1" Grid.Row="1"></Canvas>
    </Grid>
</Window>
xaml.cs文件是具体的实现,主要功能是在文本框内容改变的时候动态构成Code 39条形码:

using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
 
namespace Code39Demo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Textbox1.Focus();
        }
 
        private void Textbox1_TextChanged(object sender, TextChangedEventArgs e)
        {
            Canvas1.Children.Clear();
 
            TextBox textBox = e.Source as TextBox;
            if (textBox != null)
            {
                string content = textBox.Text;
                if (string.IsNullOrEmpty(content))
                {
                    textBox.BorderBrush = null;
                    return;
                }
 
                string code = string.Empty;
                bool result = TryConvertCode(content, out code);
                if (!result)
                {
                    textBox.BorderBrush = new SolidColorBrush(Colors.Red);
                    textBox.BorderThickness = new Thickness(2);
                    return;
                }
                else
                {
                    textBox.BorderBrush = null;
                }
 
                int thinWidth = 3;
                int thickWidth = 3 * thinWidth;
                int currentPos = 10;
 
                for (int i = 0; i < code.Length; i++)
                {
                    Rectangle r = new Rectangle();
                    r.Height = 150;
 
                    Canvas.SetLeft(r, currentPos);
 
                    switch (code[i])
                    {
                        case 'N':
                            {
                                r.Fill = new SolidColorBrush(Colors.Black);
                                currentPos += thinWidth;
                                r.Width = thinWidth;
                                break;
                            }
                        case 'n':
                            {
                                r.Fill = new SolidColorBrush(Colors.White);
                                currentPos += thinWidth;
                                r.Width = thinWidth;
                                break;
                            }
                        case 'W':
                            {
                                r.Fill = new SolidColorBrush(Colors.Black);
                                currentPos += thickWidth;
                                r.Width = thickWidth;
                                break;
                            }
                        case 'w':
                            {
                                r.Fill = new SolidColorBrush(Colors.White);
                                currentPos += thickWidth;
                                r.Width = thickWidth;
                                break;
                            }
                    }
 
                    Canvas1.Children.Add(r);
                }
            }
        }
 
        private bool TryConvertCode(string content, out string code)
        {
            code = string.Empty;
            string c = "*" + content + "*";
            StringBuilder sb = new StringBuilder();
 
            for (int i = 0; i < c.Length; i++)
            {
                string value = string.Empty;
                bool result = _code39Map.TryGetValue(c[i], out value);
                if (!result)
                {
                    return false;
                }
 
                sb.Append(value);
                sb.Append('n');
            }
 
            code = sb.Remove(sb.Length - 1, 1).ToString();
 
            return true;
        }
 
        private static Dictionary<char, string> _code39Map = new Dictionary<char, string>();
 
        static MainWindow()
        {
            _code39Map['0'] = "NnNwWnWnN";
            _code39Map['1'] = "WnNwNnNnW";
            _code39Map['2'] = "NnWwNnNnW";
            _code39Map['3'] = "WnWwNnNnN";
            _code39Map['4'] = "NnNwWnNnW";
            _code39Map['5'] = "WnNwWnNnN";
            _code39Map['6'] = "NnWwWnNnN";
            _code39Map['7'] = "NnNwNnWnW";
            _code39Map['8'] = "WnNwNnWnN";
            _code39Map['9'] = "NnWwNnWnN";
                                        
            _code39Map['A'] = "WnNnNwNnW";
            _code39Map['B'] = "NnWnNwNnW";
            _code39Map['C'] = "WnWnNwNnN";
            _code39Map['D'] = "NnNnWwNnW";
            _code39Map['E'] = "WnNnWwNnN";
            _code39Map['F'] = "NnWnWwNnN";
            _code39Map['G'] = "NnNnNwWnW";
            _code39Map['H'] = "WnNnNwWnN";
            _code39Map['I'] = "NnWnNwWnN";
            _code39Map['J'] = "NnNnWwWnN";
            _code39Map['K'] = "WnNnNnNwW";
            _code39Map['L'] = "NnWnNnNwW";
            _code39Map['M'] = "WnWnNnNwN";
            _code39Map['N'] = "NnNnWnNwW";
            _code39Map['O'] = "WnNnWnNwN";
            _code39Map['P'] = "NnWnWnNwN";
            _code39Map['Q'] = "NnNnNnWwW";
            _code39Map['R'] = "WnNnNnWwN";
            _code39Map['S'] = "NnWnNnWwN";
            _code39Map['T'] = "NnNnWnWwN";
            _code39Map['U'] = "WwNnNnNnW";
            _code39Map['V'] = "NwWnNnNnW";
            _code39Map['W'] = "WwWnNnNnN";
            _code39Map['X'] = "NwNnWnNnW";
            _code39Map['Y'] = "WwNnWnNnN";
            _code39Map['Z'] = "NwWnWnNnN";
                                        
            _code39Map['-'] = "NwNnNnWnW";
            _code39Map['.'] = "NwNnNnWnW";
            _code39Map[' '] = "NwWnNnWnN";
            _code39Map['$'] = "NwNwNwNnN";
            _code39Map['/'] = "NwNwNnNwN";
            _code39Map['+'] = "NwNnNwNwN";
            _code39Map['%'] = "NnNwNwNwN";
                                        
            _code39Map['*'] = "NwNnWnWnN";
        }
    }
}

各字符对应编码中,W表示黑色宽条,w表示白色宽条,N表示黑色窄条,n表示白色窄条。需要注意的是,Code 39的相邻字符间需要有一个白色窄条用于分隔。

这个Demo还欠缺Code 39中校验码的处理(通常不需要),如果有需要的话,可以在此基础上补充,相信并不是困难的工作。

原文同步发布于我的个人博客


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: WPF的TabControl控件可以通过动态生成选项卡的方式来添加窗体,具体步骤如下: 1. 首先,在XAML中添加一个TabControl控件,作为主窗口的子控件。 2. 在后台代码中,创建一个ObservableCollection对象,用于存储选项卡的集合。例如,可以创建一个名为TabItems的ObservableCollection<TabItem>对象。 3. 创建一个方法,该方法用于动态生成选项卡并添加窗体。该方法可以根据需求接收窗体的相关参数,如窗体的名称、标题、内容等。 4. 在该方法中,创建一个新的TabItem对象,并设置其Header属性为窗体的标题。 5. 创建一个新的Window对象,并设置其Content属性为窗体的内容。这里可以根据需要选择合适的窗体控件,如Grid、StackPanel等。 6. 将新创建的Window对象设置为TabItem对象的Content属性。 7. 将新创建的TabItem对象添加到TabItems集合中。 8. 将TabItems集合绑定到TabControl控件的ItemsSource属性,以便在界面上显示动态生成的选项卡。 9. 最后,可以在需要的时候调用该方法来动态生成选项卡并添加窗体。 通过以上步骤,我们可以实现在WPF的TabControl控件中动态生成选项卡并添加窗体的功能。这样可以方便地根据需要动态地添加和关闭选项卡,提升用户体验。 ### 回答2: 在WPF中,可以通过动态生成选项卡来实现TabControl的功能。首先,我们需要创建一个TabControl控件。 ```xaml <TabControl x:Name="tabControl" /> ``` 接下来,在代码中,我们可以通过循环方式动态生成选项卡,并添加需要的窗体。 ```csharp var tabItem = new TabItem(); tabItem.Header = "选项卡标题"; var newWindow = new Window() { Title = "新窗体", Content = new UserControl() // 窗体内容可以是自定义的UserControl }; tabItem.Content = newWindow; tabControl.Items.Add(tabItem); ``` 通过上述代码,我们就可以动态生成一个选项卡,并将需要添加的窗体作为其内容添加进去。每次循环创建新的选项卡和窗体,就可以实现动态生成多个选项卡的效果。 需要注意的是,添加的窗体内容可以是自定义的UserControl,可以根据实际需要进行修改。另外,动态生成选项卡的过程可以根据实际业务需求进行处理,可以通过循环、条件判断等方式灵活处理。 ### 回答3: 在WPF中,可以通过代码动态生成TabControl的选项卡,并添加窗体。以下是一个简单的示例: 首先,需要在XAML中创建一个TabControl的实例,设置一个名为"tabControl"的控件: ``` <TabControl x:Name="tabControl"/> ``` 然后,在后台的C#代码中使用以下方法来动态生成选项卡和添加窗体: ```csharp // 创建一个新的TabItem TabItem newTab = new TabItem(); // 设置TabItem的标题 newTab.Header = "选项卡标题"; // 创建一个新的窗体,可以是任何自定义的窗体 Window newWindow = new Window(); // 设置窗体的内容 newWindow.Content = "窗体内容"; // 设置窗体的标题 newWindow.Title = "窗体标题"; // 将窗体添加到选项卡中 newTab.Content = newWindow; // 将选项卡添加到TabControl中 tabControl.Items.Add(newTab); ``` 通过上述代码,我们可以在TabContol中动态生成一个新的选项卡,并将窗体作为其内容添加进去。可以根据需要重复上述代码,在TabControl中生成任意数量的选项卡和窗体。 需要注意的是,动态生成的选项卡和窗体可以通过命令或事件与其他控件进行交互,并具有自定义的操作和逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值