专注于按钮时读取条码扫描器条目
Read barcode scanner entry when focused on button
我使用按键事件的条形码扫描器侦听器如下(来自另一个 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();
}
}
现在我的问题是,使用我的扫描仪,当我将焦点放在一个按钮上时,"button_click" 事件会在 之前触发 BarCodeScanned
.
关于如何防止这种情况发生的任何提示?可能禁用按钮?
编辑:我添加了按钮单击事件处理程序和表单的构造函数。请注意,我在 for 本身上有一个按钮,因此它会自动聚焦。触发 "button click" 事件可防止触发条形码事件(此处显示消息框)。请注意,我是否注册按钮点击事件没有任何区别...
必要时您可以将焦点设置回目标。
您没有显示足够的代码来涵盖所有基础,但这应该给您一个想法:
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
因为按下而没有获得焦点,但是因为没有其他东西可以获得焦点你可以通过向表单 和 按钮添加 PreviewKeyPress
事件来解决。设置 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);
}
为此,将处理击键的代码移动到一个函数中:
void processKey(Keys key)
{
// check timing (keystrokes within 100 ms)
TimeSpan elapsed = (DateTime.Now - _lastKeystroke);
if (elapsed.TotalMilliseconds > 100)
_barcode = ""; // Clear();
// record keystroke & timestamp
_barcode += (char)key; // e.KeyChar);
_lastKeystroke = DateTime.Now;
// process barcode
if (key == Keys.Enter && _barcode.Length > 0)
{
string msg = new String(_barcode.ToArray());
if (BarCodeScanned != null)
{
BarCodeScanned(sender,
new BarcodeScannedEventArgs(new String(_barcode.ToArray())));
}
BarCodeScanned(_barcode);
_barcode.Clear();
}
}
我只是重新格式化 TaW's 答案以反映点击 "Enter" 不应触发空条码扫描事件的情况。
注意 使用原始参数,我能够很容易地从键盘触发条码扫描事件。因此,我将经过的打字时间减少到 50 毫秒,并确保 _barcode
至少有 7 个字符长。这适用于 EAN-8 和 EAN-13 格式。即使用双手,我也无法错误地触发条形码理智事件。
UPDATE 逻辑错误,因为如果处理了事件键,ProcessCmdKey
应该 return 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;
}
我使用按键事件的条形码扫描器侦听器如下(来自另一个 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();
}
}
现在我的问题是,使用我的扫描仪,当我将焦点放在一个按钮上时,"button_click" 事件会在 之前触发 BarCodeScanned
.
关于如何防止这种情况发生的任何提示?可能禁用按钮?
编辑:我添加了按钮单击事件处理程序和表单的构造函数。请注意,我在 for 本身上有一个按钮,因此它会自动聚焦。触发 "button click" 事件可防止触发条形码事件(此处显示消息框)。请注意,我是否注册按钮点击事件没有任何区别...
必要时您可以将焦点设置回目标。
您没有显示足够的代码来涵盖所有基础,但这应该给您一个想法:
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
因为按下而没有获得焦点,但是因为没有其他东西可以获得焦点你可以通过向表单 和 按钮添加 PreviewKeyPress
事件来解决。设置 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);
}
为此,将处理击键的代码移动到一个函数中:
void processKey(Keys key)
{
// check timing (keystrokes within 100 ms)
TimeSpan elapsed = (DateTime.Now - _lastKeystroke);
if (elapsed.TotalMilliseconds > 100)
_barcode = ""; // Clear();
// record keystroke & timestamp
_barcode += (char)key; // e.KeyChar);
_lastKeystroke = DateTime.Now;
// process barcode
if (key == Keys.Enter && _barcode.Length > 0)
{
string msg = new String(_barcode.ToArray());
if (BarCodeScanned != null)
{
BarCodeScanned(sender,
new BarcodeScannedEventArgs(new String(_barcode.ToArray())));
}
BarCodeScanned(_barcode);
_barcode.Clear();
}
}
我只是重新格式化 TaW's 答案以反映点击 "Enter" 不应触发空条码扫描事件的情况。
注意 使用原始参数,我能够很容易地从键盘触发条码扫描事件。因此,我将经过的打字时间减少到 50 毫秒,并确保 _barcode
至少有 7 个字符长。这适用于 EAN-8 和 EAN-13 格式。即使用双手,我也无法错误地触发条形码理智事件。
UPDATE 逻辑错误,因为如果处理了事件键,ProcessCmdKey
应该 return 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;
}