专注于按钮时读取条形码扫描仪条目

时间:2016-01-22 09:57:14

标签: c# event-handling barcode-scanner

我使用条形码扫描仪监听器使用按键事件如下(来自另一篇文章):

public Form2() {
     InitializeComponent();
     //
     this.KeyPreview = true;
     this.KeyPress += Form2_KeyPress;
     this.Button1_click += (s, e) => {
           // --- even if I don't close the form, the click event firing
           // prevents the "Process barcode" to execute...
           //this.Close();
           Console.Writeln("hitting focused button.");
      }
 }
 public void KeyPress_scanner_preview(object sender, KeyPressEventArgs e) {
      // check timing (keystrokes within 100 ms)
      TimeSpan elapsed = (DateTime.Now - _lastKeystroke);
      if (elapsed.TotalMilliseconds > 100)
        _barcode.Clear();

      // record keystroke & timestamp
      _barcode.Add(e.KeyChar);
      _lastKeystroke = DateTime.Now;

      // process barcode
      if (e.KeyChar == 13 && _barcode.Count > 0) {
        string msg = new String(_barcode.ToArray());
        MessageBox.Show("Read barcode: " + new String(_barcode.ToArray()));
        _barcode.Clear();
      }
    }

现在我的问题是,使用我的扫描仪,当我专注于按钮时,“button_click”事件会触发之前 BarCodeScanned被触发。

有关如何防止这种情况发生的任何提示?可能会禁用按钮?

编辑:我添加了按钮单击事件处理程序和表单的构造函数。请注意,我有一个单独的按钮,因此自动聚焦。触发“按钮单击”事件可防止条形码事件被触发(此处显示消息框)。请注意,无论我是否注册按钮点击事件都没有任何区别......

2 个答案:

答案 0 :(得分:1)

您可以在必要时将焦点设置回目标。

您没有显示足够的代码来涵盖所有基础,但这应该会给您一个想法:

private void button1_Click(object sender, EventArgs e)
{
    // do the real click work..:

    // then reset the focus
    resetFocus();
}

void resetFocus() // rest focus to a textbox and clear the selection
{
    textBox1.Focus();
    textBox1.SelectionLength = 0;
    textBox1.SelectionStart = textBox1.Text.Length;
}

更新1:

如果Button没有得到关注,因为已按下,但由于没有其他任何内容可以获得关注,您可以通过添加{{1}来解决问题}表格按钮的事件。设置PreviewKeyPress

更新2: 如果您有许多按钮和其他内容,您仍然可以通过覆盖Form.KeyPreview=true来解决问题。在表单上使用ProcessCmdKey的常规方式不起作用,因为PreviewKeyDown在传递之前窃取了Buttons密钥。现在无需设置Enter

Form.KeyPreview

对于此移动,将键击处理为函数的代码:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == Keys.Enter)
    {
        processKey((char) keyData);  // we need the Enter key
        return false;                // do not steal it!
    }
    processKey((char)keyData);       // process other keys
    return base.ProcessCmdKey(ref msg, keyData);
}

答案 1 :(得分:0)

我只是重新格式化TaW's回答,以反映点击"输入"不应该发射空的条形码扫描事件。

注意使用原始参数,我能够非常轻松地从keayboard发射条形码扫描事件。因此,我将经过的打字时间减少到50毫秒,并确保_barcode至少有7个字符长。这适用于EAN-8和EAN-13格式。即使用双手,我也无法错误地发射条形码的事件。

更新逻辑错误,因为如果处理了事件密钥,ProcessCmdKey应返回true。我在更新的代码中实现了逻辑。

这里是代码:

DateTime _lastKeystroke = new DateTime(0);
string _barcode = string.Empty;

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    bool res = processKey(keyData);
    return keyData == Keys.Enter ? res : base.ProcessCmdKey(ref msg, keyData);
}

bool processKey(Keys key)
{
    // check timing (>7 keystrokes within 50 ms)
    TimeSpan elapsed = (DateTime.Now - _lastKeystroke);
    if (elapsed.TotalMilliseconds > 50)
    {
        _barcode = string.Emtpy;
    }
    // record keystroke & timestamp
    _barcode += (char)key;
    _lastKeystroke = DateTime.Now;
    // process barcode
    // --- barcode length should be > 1, not 0 (as the return char
    // itself was added above)
    if (key == Keys.Enter && _barcode.Length > 1)
    {
        string msg = new String(_barcode.ToArray());
        MessageBox.Show(msg);
        _barcode = string.Empty;
        return true;
    }
    return false;
}