C#WinForm +条码扫描器输入,TextChanged错误

时间:2013-01-23 10:16:50

标签: c# .net winforms barcode barcode-scanner

更新:解决方案


我有一个Winform,label1将使用从条形码扫描器通过txtBoxCatchScanner收到的输入(MemberID)显示从SQL搜索返回的一些信息。

情景是当人们通过接收时,人们会在扫描仪下刷他们的会员ID卡,并且Winform会自动对该会员ID进行搜索并在接待员的PC上返回他们的信息,例如“过期会员”等,其中包含winForm她桌面的一角。

我在第一次滑动(例如,第一人称)时,以下代码正常工作

数字MemberID,例如00888出现在文本框中,ADO.NET从SQL中提取数据并显示它。

有一点需要注意,光标位于memberID的末尾:00888 |

到目前为止一切顺利,然后:

当滑动2(例如下一个人)发生时

他们的号码(比如说00999)会被放到txtBox中第一个的末尾,例如:0088800999所以当TextChanged Fires它自然搜索0088800999而不是00999 ....

我试过了:

txtBoxCatchScanner.Clear();

txtBoxCatchScanner.Text = "";

和 重新加载表格

在我的代码末尾“刷新”文本框

但我想他们会触发TextChanged事件

如何重新聚焦或......在上一次滑动完成其中之后,将旧数字和光标清回txtBox的开头......

我是初学者,所以我确定下面的代码很糟糕......

但是如果有人有时间,请告诉我如何解决这个问题。

更新

好好经过多次试验我已经设法让这个1/2工作了,希望有更多的经验可以帮助我完成! :P

if (txtBoxCatchScanner.Text.Length == 5)
{
label1.Text = txtBoxCatchScanner.Text; // just a label for testing .. shows the memmber ID
txtBoxCatchScanner.Select(0, 5);
}

SO扫描1,比如00888,然后突出显示,扫描2,说00997 ......甜蜜!覆盖(不附加)00888,这是事情...扫描2 0011289 ... DOH !!

问题:并非所有条形码都是5位数!它们是随机长度!! Memeber ID范围从2位数(例如25位)到10位数,并且将来会增长...

编辑:我发现的东西是条形码被视为单独按键。我认为这就是为什么下面的答案1不起作用以及大问题的原因:

例如00675来自扫描仪的输入(?输出)是:

唐:做 起来:做 下来:做 起来:做 下:D6 上:D6 下来:D7 上:D7 下来:D5 上:D5 下来:重新调整 上:返回

其他信息:条形码扫描仪是:Opticon OPL6845 USB

由于

private void txtBoxCatchScanner_TextChanged(object sender, EventArgs e)
{             
    Member member = new Member();
    member.FirstName = "";
    member.LastName = "";            

    //Get BarCode
    //VALIDATE: Is a Number           
    double numTest = 0;
    if (Double.TryParse(txtBoxCatchScanner.Text, out numTest))
    {
        //IS A NUMBER
        member.MemberID = Convert.ToInt32(txtBoxCatchScanner.Text);

        //SEARCH
        //Search Member by MemberID (barcode)
        List<Member> searchMembers = Search.SearchForMember(member);

        if (searchMembers.Count == 0)
        {
            lblAlert.Text = "No Member Found";
        }
        else
        {
            foreach (Member mem in searchMembers)
            {
                lblMemberStatus.Text = mem.MemberStatus;
                lblMemberName.Text = mem.FirstName + " " + mem.LastName;
                lblMemberID.Text = mem.MemberID.ToString();

                lblMessages.Text = mem.Notes;

                if (mem.MemberStatus == "OVERDUE") // OR .. OR .. OR ...
                {
                    lblAlert.Visible = true;
                    lblAlert.Text = "!! OVERDUE !!";

                    //PLAY SIREN aLERT SOUND
                    //C:\\WORKTEMP\\siren.wav
                    SoundPlayer simpleSound = 
                        new SoundPlayer(@"C:\\WORKTEMP\\siren.wav");
                    simpleSound.Play();
                }
                else
                {
                    lblAlert.Visible = true;
                    lblAlert.Text = mem.MemberStatus;
                }
            }
        }
    }
    else
    {
        //IS NOT A NUMBER
        lblAlert.Text = "INVALID - NOT A NUMBER";                

        ////
        //lblMemberName.Text = "";
        //lblMemberID.Text = "";
        //lblMemberID.Text = "";
    }

SOLUTION:

系统不会让我再回答我自己的问题3个小时,因为我只是新手一个帖子,所以会放在这里:

首先感谢大家的帮助和耐心。

我终于找到了一个已经完成测试但尚未完全测试的凌晨2点和睡觉时间。

跟随我的更新,我取得了成功,但遇到了可变长度的MemberID问题。我现在已经通过下面的代码克服了这个问题:

namespace SCAN_TESTING
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void txtBoxCatchScanner_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyValue == (char)Keys.Return)
        {
            e.Handled = true;

            int barcodeLength = txtBoxCatchScanner.TextLength;

            txtBoxCatchScanner.Select(0, barcodeLength);

            //TEST
            label3.Text = barcodeLength.ToString();
            //TEST
            label2.Text = txtBoxCatchScanner.Text;

        }

    }

我会将此添加到我之前的“真实”代码并在早上进行测试 但在这个阶段正在做我想要的! =]

更新:测试过它......完全符合要求:

private void txtBoxCatchScanner_KeyUp(object sender, KeyEventArgs e)
{
   if (e.KeyValue == (char)Keys.Return)
      {
            e.Handled = true;

            int barcodeLength = txtBoxCatchScanner.TextLength;

            txtBoxCatchScanner.Select(0, barcodeLength);

           //
           //INSERT ORGINAL CODE HERE. No Changes were needed.
           //


      }//end of if e.KeyValue ...
}//end txtBoxCatchScanner_KeyUp

希望将来帮助任何人! :)

再次感谢2个非常好的解决方案,我可以看到它们是如何工作的,并且学到了很多。 只是在我的情况下不起作用 - 更可能是由于我自己或我的错误/不理解,或扫描仪类型。

3 个答案:

答案 0 :(得分:4)

您使用的条形码扫描仪似乎可用作HID - 键盘仿真。我所知道的每个简单的条形码扫描仪(我每天都在使用它们)可以选择为扫描的条形码指定后缀。将后缀更改为CRLF并在表单中添加默认按钮。扫描以CRLF结尾的条形码将自动“按下按钮”。

将执行检查的代码从TextChanged事件移动到按钮Click事件的事件处理程序,并删除TextChanged事件处理程序。然后,单击该按钮时,还要清除文本框并将焦点设置回文本框。

现在你应该好好去。

您可以轻松检查条形码扫描仪是否已配置正确的后缀:打开记事本并扫描一些条形码。如果它们都出现在不同的行上,那么一切都很好。否则,您需要扫描扫描仪手册中的一些配置条形码。

总结一下,这应该是按钮的Click事件的代码:

private void btnCheckMember_Click(object sender, EventArgs e)
{             
    Member member = new Member();
    member.FirstName = "";
    member.LastName = "";            

    string memberText = txtBoxCatchScanner.Text.Trim();
    txtBoxCatchScanner.Text = String.Empty;

    int numTest = 0;
    if (String.IsNullOrEmpty(memberText) ||!Int32.TryParse(memberText, out numTest))
    {
        //IS NOT A NUMBER
        lblAlert.Text = "INVALID - NOT A NUMBER";                
        return;
    }

    member.MemberID = numTest;
    List<Member> searchMembers = Search.SearchForMember(member);

    if (searchMembers.Count == 0)
    {
        lblAlert.Text = "No Member Found";
    }
    else
    {
        foreach (Member mem in searchMembers)
        {
            lblMemberStatus.Text = mem.MemberStatus;
            lblMemberName.Text = mem.FirstName + " " + mem.LastName;
            lblMemberID.Text = mem.MemberID.ToString();

            lblMessages.Text = mem.Notes;

            if (mem.MemberStatus == "OVERDUE") // OR .. OR .. OR ...
            {
                lblAlert.Visible = true;
                lblAlert.Text = "!! OVERDUE !!";

            SoundPlayer simpleSound = new SoundPlayer(@"C:\\WORKTEMP\\siren.wav");
            simpleSound.Play();
        }
        else
        {
            lblAlert.Visible = true;
            lblAlert.Text = mem.MemberStatus;
        }
    }
}

此解决方案避免了以下问题:

  1. 在文本框的内容中添加/删除每个字符时触发事件(扫描条形码时也是如此:它们是逐个添加的,就好像它们是在键盘上输入一样)
  2. 由1.在每个输入的字符上执行成员检查的问题
  3. 由2.如果数据库中有成员XYZ,则永远不会找到成员XY的问题,因为检查在找到XY之后停止
  4. 由3.问题导致成员XY也找不到,但只有成员Z,因为在3.中文本框被清除,Z是唯一的字符正在进入。

答案 1 :(得分:3)

我不确定实际问题是什么。

txtBoxCatchScanner.Clear();
txtBoxCatchScanner.Text = "";

都会触发“已更改”事件。 但他们也清除了这个盒子。所以这应该是你想要做的。

您可以在开头检查该框是否实际为空,如果是,则返回。像:

if(txtBoxCatchScanner.Text == "" |txtBoxCatchScanner.Text == string.Empty)
return;

如果盒子是空的,那么没有其他事情发生。

如果我误解了您的问题,请说明,我会尽力提供帮助。

此致

编辑:

如果看起来像这样,你的功能应该有效:

    private void txtBoxCatchScanner_TextChanged(object sender, EventArgs e)
{             
Member member = new Member();
member.FirstName = "";
member.LastName = "";            

if(txtBoxCatchScanner.Text == "" | txtBoxCatchScanner.Text == string.Empty)
return;    // Leave function if the box is empty

//Get BarCode
//VALIDATE: Is a Number           
int numTest = 0;
if (int.TryParse(txtBoxCatchScanner.Text, out numTest))
{
    //IS A NUMBER
    //member.MemberID = Convert.ToInt32(txtBoxCatchScanner.Text);
    member.MemberID = numTest; // you already converted to a number...
    //SEARCH
    //Search Member by MemberID (barcode)
    List<Member> searchMembers = Search.SearchForMember(member);

    if (searchMembers.Count == 0)
    {
        lblAlert.Text = "No Member Found";
    }
    else
    {
        foreach (Member mem in searchMembers)
        {
            lblMemberStatus.Text = mem.MemberStatus;
            lblMemberName.Text = mem.FirstName + " " + mem.LastName;
            lblMemberID.Text = mem.MemberID.ToString();

            lblMessages.Text = mem.Notes;

            if (mem.MemberStatus == "OVERDUE") // OR .. OR .. OR ...
            {
                lblAlert.Visible = true;
                lblAlert.Text = "!! OVERDUE !!";

                //PLAY SIREN aLERT SOUND
                //C:\\WORKTEMP\\siren.wav
                SoundPlayer simpleSound = 
                    new SoundPlayer(@"C:\\WORKTEMP\\siren.wav");
                simpleSound.Play();
            }
            else
            {
                lblAlert.Visible = true;
                lblAlert.Text = mem.MemberStatus;
            }
        }
    }
}
else
{
    //IS NOT A NUMBER
    lblAlert.Text = "INVALID - NOT A NUMBER";                

    ////
    //lblMemberName.Text = "";
    //lblMemberID.Text = "";
    //lblMemberID.Text = "";
}
txtBoxCatchScanner.Clear();
}

答案 2 :(得分:1)

在下一个textChange事件中清除textBox的最佳方法。

插入此行

txtBoxCatchScanner.SelectAll();

在TextChange函数的末尾..这将选择文本,以便我可以在下一个事件中轻松替换。