#c#
#c#
Вопрос:
Я нахожусь в процессе создания POS
системы с использованием C #, и у меня возникла проблема с текстовым полем для чтения штрих-кода.
Я хочу считывать штрих-код со сканера, либо когда текстовое поле имеет фокус, либо нет. Опять же, я хочу, чтобы в текстовом поле была возможность поиска продукта вручную, то есть пользователь вводит штрих-код, а затем нажимает клавишу ввода. Полученный штрих-код должен использоваться для запроса MySQL.
Я использовал этот код для считывания штрих-кода со сканера, когда мое текстовое поле имеет фокус или нет, но проблема в том, что когда я хочу выполнить поиск продукта вручную с помощью клавиши enter, метод запроса базы данных вызывается дважды, и я не понимаю почему. Нужна помощь, чтобы предотвратить повторный вызов функции, а также предоставить функциональность для поиска штрих-кода при вводе и когда текстовое поле не имеет фокуса, который получает ввод от сканера
private string _barcode = "";
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)//read when no focus
{
char c = (char)keyData;
if (char.IsNumber(c))
_barcode = c;
if (c == (char)Keys.Return)
{
read_scanner(_barcode);
_barcode = "";
}
return base.ProcessCmdKey(ref msg, keyData);
}
Это мой код для поиска вручную
private void txtbarcode_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// onQuery = true;
read_scanner(txtbarcode.Text);
}
}
И вот мой метод, который вызывается дважды, когда я нажимаю клавишу ввода
Product product;
public void read_scanner(string barcode)//this method is getting invoked twice when i search product manually
{
//
product = HibernateDao.getRecord("from Product u where u.barcode='" barcoded "'");
if (product != null)
{
pos_datagrid.Rows.Add(barcode, product.product_name, product.product_desc, null, "1", null, product_Cost);
}
else
{
AppUtil.showErrorBox("Invalid bar code!!");
}
}
Комментарии:
1. Просто проверка работоспособности, вы уверены, что метод read_scanner вызывается дважды одним и тем же экземпляром события ? Или событие KeyDown вызывается более одного раза?
2. Я только что скопировал ваш код в пустой проект Win Forms с текстовым полем (txtbarcode) и кнопкой. Когда я устанавливаю фокус между кнопкой и текстовым полем,
ProcessCmdKey
метод срабатывает каждый раз, независимо от того, какой фокус находится. Но событие KeyDown текстового поля никогда не срабатывает.ProcessCmdKey
Метод передает ключ своему родительскому элементу управления, поэтому независимо от того, какой элемент управления имеет фокус, он всегда должен срабатывать, что я и вижу. Мне интересно, срабатывает ли ваше событие KeyDown также, хотя мое — нет. Попробуйте на мгновение удалить событие KeyDown и посмотреть, работает ли оно по-прежнему с фокусом и без него.3. Если это не решает проблему, я также видел, как другие люди упоминали ошибку в некоторых случаях, когда событие KeyUp срабатывает дважды. Они решили эти проблемы, используя вместо этого событие KeyUp. Вам также следует попробовать установить
e.Handled = true;
в событии KeyUp / KeyDown.4. @Daniel Я не понимаю, что вы говорите о e.Handled=true
5. Да, но ваш метод read _scanner может быть вызван как методом ProcessCmdKey, так и методом txtbarcode_KeyDown. Вам нужно выяснить, вызывает ли один из этих методов его дважды, и если да, то какой именно. Или, если вызываются оба метода, это означает, что они вызывают его по одному разу каждый одновременно.
Ответ №1:
ProcessCmdKey
Это виртуальный метод для all Forms
, который прослушивает все ключи и возвращает, true
если это был командный ключ и false
для других ключей, поэтому вам может вообще не понадобиться внедрять KeyDown
.
Я немного изменил код, чтобы использовать a StringBuilder
и добавить к нему значения StringBuilder
.
StringBuilder _barcodeBuilder = new StringBuilder();
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData != Keys.Return)
{
switch (keyData)
{
case Keys.NumPad0:
_barcodeBuilder.Append(0);
break;
case Keys.NumPad1:
_barcodeBuilder.Append(1);
break;
case Keys.NumPad2:
_barcodeBuilder.Append(2);
break;
case Keys.NumPad3:
_barcodeBuilder.Append(3);
break;
//and so on for the rest of the numpad keys
default:
_barcodeBuilder.Append((char)keyData);
break;
}
}
else
{
MessageBox.Show(this, _barcodeBuilder.ToString());
//read_scanner(_barcodeBuilder.ToString());
textBox1.Clear();
_barcodeBuilder = new StringBuilder();
}
return base.ProcessCmdKey(ref msg, keyData);
}
Клавиши Numpad немного странные, поэтому вы можете обработать их с помощью инструкции switch.
Ответ №2:
Источник вашей проблемы неясен. Хотя, если вы хотите отследить источник того, что запускает ваш метод, используйте System.Environment.StackTrace
и выводите это как отладочное сообщение. Возможно, для этого вам придется использовать конфигурацию «Debug».
Комментарии:
1. Исходным триггером является ProcessCmdKey
2. Вы сказали, что метод вызывается дважды, верно? Ваше отладочное сообщение должно сработать дважды, если метод, в котором оно находится, вызывается дважды. Если трассировка стека обоих идентична, то вы знаете, что это действительно проблема с самим триггером (что может быть наименее вероятным). Если вы получаете только одну трассировку стека, это означает, что метод вызывается только один раз. Если вы получаете две разные трассировки стека, это означает, что вы случайно запустили свой метод по двум разным путям выполнения.