C# WinForm + Barcode Scanner input, TextChanged Error
Solution 1
I´m not exactly sure what the actual problem is.
txtBoxCatchScanner.Clear();
txtBoxCatchScanner.Text = "";
both trigger the "Changed" Event. But they also clear the box. So that should be what you want to do.
You could check at the beginning if the box is actually empty, and return in case it is. Like:
if(txtBoxCatchScanner.Text == "" |txtBoxCatchScanner.Text == string.Empty)
return;
So nothing else happens, if the box is empty.
If I misunderstood your problem, please specify and I will try to help.
Regards
EDIT:
Your function should work if it looked something like this:
private void txtBoxCatchScanner_TextChanged(object sender, EventArgs e)
{
Member member = new Member();
member.FirstName = "";
member.LastName = "";
if(txtBoxCatchScanner.Text == "" | txtBoxCatchScanner.Text == string.Empty)
return; // Leave function if the box is empty
//Get BarCode
//VALIDATE: Is a Number
int numTest = 0;
if (int.TryParse(txtBoxCatchScanner.Text, out numTest))
{
//IS A NUMBER
//member.MemberID = Convert.ToInt32(txtBoxCatchScanner.Text);
member.MemberID = numTest; // you already converted to a number...
//SEARCH
//Search Member by MemberID (barcode)
List<Member> searchMembers = Search.SearchForMember(member);
if (searchMembers.Count == 0)
{
lblAlert.Text = "No Member Found";
}
else
{
foreach (Member mem in searchMembers)
{
lblMemberStatus.Text = mem.MemberStatus;
lblMemberName.Text = mem.FirstName + " " + mem.LastName;
lblMemberID.Text = mem.MemberID.ToString();
lblMessages.Text = mem.Notes;
if (mem.MemberStatus == "OVERDUE") // OR .. OR .. OR ...
{
lblAlert.Visible = true;
lblAlert.Text = "!! OVERDUE !!";
//PLAY SIREN aLERT SOUND
//C:\\WORKTEMP\\siren.wav
SoundPlayer simpleSound =
new SoundPlayer(@"C:\\WORKTEMP\\siren.wav");
simpleSound.Play();
}
else
{
lblAlert.Visible = true;
lblAlert.Text = mem.MemberStatus;
}
}
}
}
else
{
//IS NOT A NUMBER
lblAlert.Text = "INVALID - NOT A NUMBER";
////
//lblMemberName.Text = "";
//lblMemberID.Text = "";
//lblMemberID.Text = "";
}
txtBoxCatchScanner.Clear();
}
Solution 2
The barcode scanner you use seems to function as a HID - a keyboard emulation. Every simple barcode scanner I know (and I'm working with them on a daily basis) has the option of specifying a suffix for the scanned barcode. Change the suffix to CRLF
and add a default button to your form. Scanning a barcode that ends with CRLF
will then automatically "push the button".
Move the code that performs the checks from TextChanged
event in to the event handler for the buttons Click
event and remove the TextChanged
event handler. Then, when the button is clicked, also clear the text box and set the focus back to the text box.
You should be good to go, now.
You can easily check whether the barcode scanner already has the correct suffix configured: Open up Notepad and scan some barcodes. If they all appear on separate lines, then everything's fine. Otherwise you'll need to scan some configuration barcodes from the scanner's manual.
To sum it all up, this should be the code for the button's Click
event:
private void btnCheckMember_Click(object sender, EventArgs e)
{
Member member = new Member();
member.FirstName = "";
member.LastName = "";
string memberText = txtBoxCatchScanner.Text.Trim();
txtBoxCatchScanner.Text = String.Empty;
int numTest = 0;
if (String.IsNullOrEmpty(memberText) ||!Int32.TryParse(memberText, out numTest))
{
//IS NOT A NUMBER
lblAlert.Text = "INVALID - NOT A NUMBER";
return;
}
member.MemberID = numTest;
List<Member> searchMembers = Search.SearchForMember(member);
if (searchMembers.Count == 0)
{
lblAlert.Text = "No Member Found";
}
else
{
foreach (Member mem in searchMembers)
{
lblMemberStatus.Text = mem.MemberStatus;
lblMemberName.Text = mem.FirstName + " " + mem.LastName;
lblMemberID.Text = mem.MemberID.ToString();
lblMessages.Text = mem.Notes;
if (mem.MemberStatus == "OVERDUE") // OR .. OR .. OR ...
{
lblAlert.Visible = true;
lblAlert.Text = "!! OVERDUE !!";
SoundPlayer simpleSound = new SoundPlayer(@"C:\\WORKTEMP\\siren.wav");
simpleSound.Play();
}
else
{
lblAlert.Visible = true;
lblAlert.Text = mem.MemberStatus;
}
}
}
This solution avoids the following problems:
- The event being triggered upon every character added/removed from the content of the text box (which is also the case when scanning a barcode: They are added one by one as if they were entered on a keyboard)
- Resulting from 1. the problem that a member check is performed upon every entered character
- Resulting from 2. the problem that member
XYZ
will never be found if there is a memberXY
in the database, as the check stops after findingXY
- Resulting from 3. the problem that member
XY
will also not be found, but only memberZ
, because in 3. the text box is cleared andZ
is the only character being entered.
Solution 3
The best way to clear the textBox on the next textChange event.
Insert this line
txtBoxCatchScanner.SelectAll();
at the end of TextChange function.. This will select the text, so that i can be replaced easily on the next event.
user1994097
Beginner Software Developer / Programmer. Appreciate the help! =]
Updated on June 25, 2022Comments
-
user1994097 about 2 years
UPDATE: SOLUTION AT END
I have a Winform, label1 will display some info returned from a SQL Search using the input (MemberID) received from barcode scanner via
txtBoxCatchScanner
.Scenario is people swiping their MemberID Cards under the scanner as they pass through reception and the Winform automatically doing a Search on that MemberID and returning their info including for example "Expired Membership" etc on the receptionist's PC which has the winForm in a corner of her desktop.
I have the Below Code working fine on first swipe (eg. first person)
The number MemberID, for example 00888 comes up in the text box, ADO.NET pulls the data from SQL and displays it fine.
one thing to note maybe, the cursor is at the end of the memberID: 00888|
All good so far, THEN:
when swipe 2 (eg. next person) happens
their number (say, 00999) gets put onto the end of the first in the txtBox eg: 0088800999 so naturally when TextChanged Fires it searches for 0088800999 instead of 00999 ....
I've tried:
txtBoxCatchScanner.Clear();
and
txtBoxCatchScanner.Text = "";
and reloading the form
at the end of my code to "refresh" the text box
but i guess they trigger the TextChanged Event
How can i refocus or ... clear the old number and cursor back to start of txtBox after the previous swipe has done its stuff...
I'm a beginner so I'm sure the code below is pretty crap....
But if anyone has time, please let me know how fix it to do what i want.
UPDATE:
Ok after much experimenting I''ve managed to get this 1/2 working now hopefully someone more experience can help me to completion! :P
if (txtBoxCatchScanner.Text.Length == 5) { label1.Text = txtBoxCatchScanner.Text; // just a label for testing .. shows the memmber ID txtBoxCatchScanner.Select(0, 5); }
SO scan 1, say 00888 , then that gets highlighted, scan 2 , say 00997 ... sweet! overwrites (not appends to) 00888 and does it's thing ... scan 2 0011289 ... DOH!!
Problem: not all barcodes are 5 digits!! they are random lengths!! Memeber ID range from 2 digit (eg. 25) to 10 digits, and would grow in the future...
Edit: Something I've discovered that is that the barcodes are read as indvidual key presses. I think this is why answer 1 below does not work and while the big probmlems:
for example with 00675 the input (?output) from the scanner is:
Down: Do Up: Do Down: Do Up: Do Down: D6 Up: D6 Down: D7 Up: D7 Down: D5 Up: D5 down: Retunn Up: Return
other info: barcode scanner is: an Opticon OPL6845 USB
Thanks
private void txtBoxCatchScanner_TextChanged(object sender, EventArgs e) { Member member = new Member(); member.FirstName = ""; member.LastName = ""; //Get BarCode //VALIDATE: Is a Number double numTest = 0; if (Double.TryParse(txtBoxCatchScanner.Text, out numTest)) { //IS A NUMBER member.MemberID = Convert.ToInt32(txtBoxCatchScanner.Text); //SEARCH //Search Member by MemberID (barcode) List<Member> searchMembers = Search.SearchForMember(member); if (searchMembers.Count == 0) { lblAlert.Text = "No Member Found"; } else { foreach (Member mem in searchMembers) { lblMemberStatus.Text = mem.MemberStatus; lblMemberName.Text = mem.FirstName + " " + mem.LastName; lblMemberID.Text = mem.MemberID.ToString(); lblMessages.Text = mem.Notes; if (mem.MemberStatus == "OVERDUE") // OR .. OR .. OR ... { lblAlert.Visible = true; lblAlert.Text = "!! OVERDUE !!"; //PLAY SIREN aLERT SOUND //C:\\WORKTEMP\\siren.wav SoundPlayer simpleSound = new SoundPlayer(@"C:\\WORKTEMP\\siren.wav"); simpleSound.Play(); } else { lblAlert.Visible = true; lblAlert.Text = mem.MemberStatus; } } } } else { //IS NOT A NUMBER lblAlert.Text = "INVALID - NOT A NUMBER"; //// //lblMemberName.Text = ""; //lblMemberID.Text = ""; //lblMemberID.Text = ""; }
SOLUTION:
The System won't let me answer my own question for another 3 hours, as I'm a newbie only 1 post, so will put here:
First thanks everyone for your help and Patience.
I Have finally figured a solition, not fully tested yet as its 2am and bed time.
following along from my updates where I had success but hit the variable length of MemberID problem. I've now overcome that with the Code below:
namespace SCAN_TESTING { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void txtBoxCatchScanner_KeyUp(object sender, KeyEventArgs e) { if (e.KeyValue == (char)Keys.Return) { e.Handled = true; int barcodeLength = txtBoxCatchScanner.TextLength; txtBoxCatchScanner.Select(0, barcodeLength); //TEST label3.Text = barcodeLength.ToString(); //TEST label2.Text = txtBoxCatchScanner.Text; } }
I'll add this to my previous "real" code and test in the morning But at this stage is doing exactly what I want! =]
Update: Tested it .. works exactly what needed:
private void txtBoxCatchScanner_KeyUp(object sender, KeyEventArgs e) { if (e.KeyValue == (char)Keys.Return) { e.Handled = true; int barcodeLength = txtBoxCatchScanner.TextLength; txtBoxCatchScanner.Select(0, barcodeLength); // //INSERT ORGINAL CODE HERE. No Changes were needed. // }//end of if e.KeyValue ... }//end txtBoxCatchScanner_KeyUp
Hope that helps anyone in the future!! :)
Thanks again for the 2 very good solutions, I can see how they work, and learnt alot. Just didn't work in my case - more likely due to myself or my error/not understanding, or scanner type.
-
default over 11 years@Soner Gönül: why did you increase the indenting when you could have removed it?
-
Admin over 11 yearsThe code that will have the issue will be the code where you assign the text to the textbox, could you show us that bit rather than the text changed event?
-
Admin over 11 yearsP.s also in your final else, you set the alert text to not a number, but you dont make the label visible
-
user1994097 over 11 yearsSorry have no idea what you mean about indenting... RhysW ... there is no other code at all apart from the public void FormScanner_Load and Public FormScanner()
-
Admin over 11 yearsOk in which case can you show me the section of code where you set the textbox's text to 00888 etc please?
-
user1994097 over 11 yearsthe text for the textbox comes from the barcode scanner and is this part: //IS A NUMBER member.MemberID = Convert.ToInt32(txtBoxCatchScanner.Text); ... if that helps
-
Admin over 11 yearswhere is the code where you do for example txtBoxCatchScanner.Text = 00889; or is that happening from a third party?
-
Uwe Keim over 11 years@Default I've removed the indent :-)
-
user1994097 over 11 yearsthe membership barcode is swiped (eg. 00889) scanner input goes to txtBoxCatchScanner which triggers TextChanged ... txtBoxCatchScannerText get's its imput from the barcode scanner .....
-
Admin over 11 yearsok so it gets its input from the scanner, can you show me that code where you get the information from the scanner and put it in the textbox, i cant help you solve the issue without seeing the code
-
user1994097 over 11 yearsthere is no other code. scanner goes into usb port... scan barcode ... barcode appears in txtbox ... the code i posted above is the complete all there is code... apart from the namespace, page load etc.. there is no other code. sorry, thanks anyways.
-
Admin over 11 yearsOk but the barcode doesnt doesnt magically appear in the textbox, somewhere somehow a piece of code is setting the text in that textbox, does your code set the textbox to be the numbers or is this a third party windows form?
-
user1994097 over 11 yearsSoner & Uwe: thanks for that, see what u mean now :P ... sorry about that, first time post.
-
default over 11 years@UweKeim thanks! :) looks much better
-
Thorsten Dittmar over 11 years@RhysW: Yes it does, if the scanner is configured as a USB keyboard, which most simple barcode scanners are by default.
-
Thorsten Dittmar over 11 yearsI just read that the member IDs have variable length: What happens if you have a member
12
and a member121
? If you have one event after each character (which is the case with theTextChanged
event - the scanner works like typing one character after the other, so after every digit,TextChanged
is triggered), you will never see member121
, as you stop after finding member12
. Do not useTextChanged
! See my approach for a clean and working solution. -
Admin over 11 years@ThorstenDittmar i was trying to disscern if he had access to the code that did it or not, and no it doesn tmagically appear, there is code for it, and i was trying to find out if he had access to it
-
Thorsten Dittmar over 11 years@RhysW: Yes, there is code for it. In the scanner's keyboard driver, or the generic Windows USB keyboard driver which is most probably used to handle such devices.
-
Admin over 11 years@ThorstenDittmar precisely! I wasnt aware if he had access to that though hence my many questions :)
-
Thorsten Dittmar over 11 years@RhysW: It's just that some people tend to forget keyboard emulation when working with COM connected scanners too long. :-)
-
Admin over 11 years@ThorstenDittmar Very True, also the solution you provided is very good, avoids more problems than just the one addressed
-
-
Admin over 11 yearsThe actual problem is that at some point the new numbers are appended to the old numbers instead of overwriting them, the setting it to blank at the end was a workaround for that, and this solution is now a workaround for the workaround XD
-
user1994097 over 11 yearshmms the problem is, if I do txtBoxCatchScanner.Clear()/etc it triggers TextChanged which then triggers a Search for memberID "" <-- i guess a "space" of which there is of course 1. not a number and 2. no member with ID of [space] and so the reponse is "Invalid number", "no member found"
-
Admin over 11 years@User1994097 Yeah because clearing it is a text changed event, but somewhere in your code you must be setting that textbox to be the numbers from the scanner, at this point of the code there is an error where instead of overwriting the old number with the new one you are appending it, which gives you the long number, i can solve the issue for you but for this you need to show the code where you SET the text box text to the numbers
-
user1994097 over 11 yearssomewhere in your code you must be setting that textbox to be the numbers from the scanner - No .. the way a barcode scanner works is: scan a barcode and it spits out the number into whatever is in focus ... open a .txt and have the cursor there and it will spit out the number to it.. have an .xls open and the cursor in a cell ... it will spit out to that cell... or in this case ... have a winform open with cursor in the textbox (?"in focus) it spits it to that textbox there is not code ... it is not like a click event ....
-
Admin over 11 years@user1994097 ok see now that piece of information would have been useful right from the very beginning, in which case this answer we are commenting on is probably the best solution, as its told that when there is a text changed event to check there is text, so this will ignore the empty "" sections
-
user1994097 over 11 yearsI assumed you know how a barcode scanner worked, but I should been clearer sorry. Sadly this solution doesn't work
-
Nicolas over 11 yearsI edited my above post. The box now gets cleared after the function completed. Which triggers the function again but immediately exits due to the "if(bla = "" |bla == string.Empty)" stuff.
-
Thorsten Dittmar over 11 years@user1994097 To RhysW's credit it should be noted that not all barcode scanners work this way. The more expensive ones can also be configured to use COM port emulation. You'd then need to open the respective COM port and retrieve information from there. This is also the preferred way, because problems as the one you're having only arise when using the keyboard wedge feature.
-
user1994097 over 11 yearsNicolas thanks, i'll give it a go. I've also updated my post with a minir lead... will try your solution now. @Thorsten: thanks for the info, and appreciate RjysW's attempt. Cheers
-
user1994097 over 11 yearsThanks I'll give this answer1 ago and let you guyes know. Many Thanks
-
Thorsten Dittmar over 11 yearsSorry to say that, but you really should not be using the
TextChanged
event! This is a bad idea, as it is called whenever you edit the text - also if the user manually enters text. That means that upon every character you add through keyboard or scanner, one event is triggered, causing a validation of the member id. DON'T! I don't want to overly advertise my approach, but it is much cleaner... -
Thorsten Dittmar over 11 yearsI just read that the member IDs have variable length: What happens if you have a member
12
and a member121
? If you have one event after each character, you will never see member121
, as you stop after finding member12
. Do not useTextChanged
! -
Thorsten Dittmar over 11 yearsNo problem. Please make sure using Notepad (or even the Visual Studio editor) that every scan is put on a separate line first - otherwise the button will not get "pressed" and you need to configure the suffix first.
-
user1994097 over 11 yearsI'll have to look into the scanner and how to "Change the suffix to CRLF" ... this scanner just plugs into the usb port and uses some kind of generic windows drivers I guess .. there not drivers supplied for it. Will try tomorrow. Thanks for help and patience everybody!
-
Thorsten Dittmar over 11 yearsWhat happens if you just scan? Are the barcodes appended in one line? For simple gun scanners, things like that are configured using special configuration barcodes. There's no special driver - they are "Generic HID devices" (Human Interface Device). Usually there's a sequence of special barcodes, like "Start Configuration" -> "Change Suffix" -> "Scan ASCII codes for suffix" -> "Finish configuration.
-
user1994097 over 11 yearsthanks. this is what the scanner outputs atm: for example with 00675 the input (?output) from the scanner is: Down: Do Up: Do Down: Do Up: Do Down: D6 Up: D6 Down: D7 Up: D7 Down: D5 Up: D5 down: Return Up: Return
-
Thorsten Dittmar over 11 yearsSeems you already get the
CRLF
. To make sure: close all programs, start Notepad and scan multiple times. Do the barcodes appear on separate lines? Alternatively: Add a button to the form, assign it'sClick
handler showing aMessageBox
, set the form'sAcceptButton
property to the new button and then run and scan - do you see theMessageBox
? If so, everything's fine already. -
user1994097 over 11 yearsdoesn't appear this scanner can do the suffix change thing. old.opticon.com/… will investigate tomorrow. nites all . thanks
-
Thorsten Dittmar over 11 yearsAs I said: most probably
CRLF
is already present, as you can see the last key pressed and released by the scanner isRETURN
. -
user1994097 over 11 yearsHave Solved the problem. Thanks for your help! Will post solution.
-
user1994097 over 11 yearsHave Solved the problem. Thanks for the help guys. WIll Post the solution