I use a barcode scanner listener using the key-press event as follows (from another post):
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();
}
}
Now my problem is that, with my scanner, when I have focus on a button, the "button_click" event fires BEFORE the BarCodeScanned
is fired.
Any hint as to how to prevent this to happen? Possibly disable the button?
EDIT: I added the button click event handler and the form's constructor. Note that I have a single button on the for itself, which is hence automatically focused. Firing the "button click" event prevents the barcode event to be fired (here, showing a messagebox). Note that whether I register the button click event or not doesn't make any difference...
I simply reformat TaW's answer to reflect the case that hitting "Enter" should NOT fire an empty barcode scanned event.
NOTE With the original parameters, I was able to fire the barcode scanned event from the keayboard quite easily. I therefore reduced the elapsed typing time to 50ms and made sure the _barcode
was at least 7 charactes long. This is ok with EAN-8 and EAN-13 formats. Even using both hands, I wasn't able to erroneously fire a barcode saneed event.
UPDATE the logic was wrong as the ProcessCmdKey
should return true
if the event key is handled. I implemented the logic in the updated code.
Here the code:
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;
}