如何在Winform中不使用TextChanged事件捕获完整的条形码值?

7
当在表格1上扫描条形码时,我会调用数据库以获取该条形码对应的物品,并打开表格2并预填充数据。
如果我使用“文本更改事件”,则每个数字都将触发一次该事件。
我无法检查条形码的长度,因为每个条形码的长度可能不同。
我应该使用哪个事件来仅在扫描条形码时进行一次调用?
我尝试了TextChanged、KeyPress和KeyDown事件,但它们都会被多次调用。
    private void txt_Barcode_TextChanged(object sender, EventArgs e)
    {
        con.Open();
        GenerateInvoice gn = new GenerateInvoice();
        string query = "SELECT * FROM dbo.Inventory WHERE Barcode = '" + txt_Barcode.Text + "' ";

        SqlCommand cmd = new SqlCommand(query, con);
        SqlDataReader dr = cmd.ExecuteReader();


        while (DR1.Read())
        {
            gn.txt_Barcode.Text = dr["Barcode"].ToString();
            gn.txt_ProductName.Text = dr["ProductName"].ToString();
            gn.txt_Price.Text = dr["SellingPrice"].ToString();
            gn.txt_QTY.Text = 1.ToString();
            gn.txt_Total.Text = dr["SellingPrice"].ToString();

        }
        con.Close();
    }

我可以使用文本框来捕获表单1上的条形码(我将在用户界面上隐藏它)。

1
条形码扫描器在代码完成时发送一个回车键。此外,大多数扫描仪可以配置为在条形码之前、之后或同时发送前缀和后缀(例如,用于识别发送条形码的扫描仪)。使用KeyDown事件。例如,if (e.KeyCode == Keys.Enter) { e.SuppressKeyPress = true; //( process) } - Jimi
1
此外,您的代码 SQL 部分还有待改进。摆脱硬编码查询,使用参数化查询,并研究使用 using() 块进行适当资源清理。 - Tanveer Badar
由于您正在像键盘一样使用条形码扫描仪,并且理想情况下只希望触发一次事件,因此您可以查看以下内容:(去抖动和节流)https://dev59.com/YV8e5IYBdhLWcg3wLYHt - Bacon
3个回答

6

这是在WedgeMode下扫描仪的结果。它基本上像一个键盘,每扫描一个字符就会创建一个文本更改事件。

有许多解决方案。

您可以使用您购买扫描仪公司提供的API,而不是使用wedge mode。

然而,一个简单的解决方案是在扫描仪上放置前缀和后缀(如ascii代码中的STXETX),通常扫描仪会提供此类设置,这样您就知道何时拥有完整的条形码数据。

当您看到有效的条形码时,就只需要触发一个事件,而不是为每个被扫描的字符都触发一个事件。


5
你可能会在这个主题下看到我的一些回答。 改进C#文本框中的条形码搜索 区分扫描仪和键盘 WPF应用程序中的条形码扫描仪 如果我再做一次(第一次是很久以前),我会选择RawInput并确定哪个设备是条形码扫描仪。使用前缀和后缀是可靠的,但是它们因设备而异。捕获原始输入抽象了这种硬件实现。
Code Project文章和下载:使用C#的原始输入处理多个键盘

看我如何从任何来源获取输入,所以我甚至不需要用户在文本框上放置光标或使用Form.KeyPreview,我可以获取由设备过滤的输入。

enter image description here

enter image description here

enter image description here


0
你可以尝试让事件等待1秒钟,或足够长的时间来完成扫描。
private async void txt_Barcode_TextChanged(object sender, EventArgs e)
{
    await Task.Delay(1000);
    con.Open();
    GenerateInvoice gn = new GenerateInvoice();
    string query = "SELECT * FROM dbo.Inventory WHERE Barcode = '" + txt_Barcode.Text + "' ";

    SqlCommand cmd = new SqlCommand(query, con);
    SqlDataReader dr = cmd.ExecuteReader();


    while (DR1.Read())
    {
        gn.txt_Barcode.Text = dr["Barcode"].ToString();
        gn.txt_ProductName.Text = dr["ProductName"].ToString();
        gn.txt_Price.Text = dr["SellingPrice"].ToString();
        gn.txt_QTY.Text = 1.ToString();
        gn.txt_Total.Text = dr["SellingPrice"].ToString();

    }
    con.Close();
}

虽然这样做可以工作,但它会在每次文本更改事件中触发一次数据库调用,有时条形码输入会被截断,最好在进行数据库调用之前至少测试 txt_Barcode 的长度。 - Jeremy Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接