I've an application that changes the text of the label to a serial number that is scanned using a barcode scanner. The code works up until I have buttons on my form.
I've tried (1) focusing on the label, (2) creating a groupbox and putting the label in the groupbox and focusing on that, using both tab order and this:
this.ActiveControl = groupBox2;
And neither work.
Here is code outlining the the application:
private void Form1_Load(object sender, EventArgs e)
{
this.ActiveControl = groupBox2;
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
this.KeyUp += new KeyEventHandler(Form1_KeyUp);
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
// if keyboard input is allowed to read
if (UseKeyboard && e.KeyData != Keys.Enter)
{
MessageBox.Show(e.KeyData.ToString());
}
/* check if keydown and keyup is not different
* and keydown event is not fired again before the keyup event fired for the same key
* and keydown is not null
* Barcode never fired keydown event more than 1 time before the same key fired keyup event
* Barcode generally finishes all events (like keydown > keypress > keyup) of single key at a time, if two different keys are pressed then it is with keyboard
*/
if (cforKeyDown != (char)e.KeyCode || cforKeyDown == '\0')
{
cforKeyDown = '\0';
_barcode.Clear();
return;
}
// getting the time difference between 2 keys
int elapsed = (DateTime.Now.Millisecond - _lastKeystroke);
/*
* Barcode scanner usually takes less than 17 milliseconds to read, increase this if neccessary of your barcode scanner is slower
* also assuming human can not type faster than 17 milliseconds
*/
if (elapsed > 17)
_barcode.Clear();
// Do not push in array if Enter/Return is pressed, since it is not any Character that need to be read
if (e.KeyCode != Keys.Return)
{
_barcode.Add((char)e.KeyData);
}
// Barcode scanner hits Enter/Return after reading barcode
if (e.KeyCode == Keys.Return && _barcode.Count > 0)
{
string BarCodeData = new String(_barcode.ToArray());
if (!UseKeyboard)
//MessageBox.Show(String.Format("{0}", BarCodeData));
label1.Text = String.Format("{0}", BarCodeData);
_barcode.Clear();
}
// update the last key press strock time
_lastKeystroke = DateTime.Now.Millisecond;
}
Again, it works as soon as I take the buttons out.
Here's a pic of my the UI:
Again, the label changes, until I start adding buttons to the WinForm.
Looking at the UI, the line that says, "Please Scan Serial..." should change when the user scans the barcode.
Related
private void UserInputText_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.D4 && e.Modifiers == Keys.Shift) || (e.KeyCode == Keys.Add))
{
if (String.IsNullOrEmpty(UserInputText.Text))
{
MessageBox.Show("Bir sayı giriniz.");
UserInputText.Clear();
return;
}
if (double.TryParse(UserInputText.Text, out sayı1))
{
CalculationResultText.Text = sayı1 + " + ";
islem = "+";
UserInputText.Clear();
}
else
{
MessageBox.Show("Sadece sayı değeri girebilirsiniz.");
UserInputText.Clear();
}
}
}
I am coding a basic forms calculator. I am trying to trigger addition function and clear the textbox when textbox is focused and user presses "+" key. "if (String.IsNullOrEmpty(UserInputText.Text)) and else conditions work well. But if no Message boxes shows up as in the
if (double.TryParse(UserInputText.Text, out sayı1)) condition, the "+" character remains in the textbox as in the image. Thanks for help.
If I understand correctly, you want to first check the character that was typed in and if it's incorrect then you want to prevent this character from appearing?
If so, then you need to set e.Handled = true property when you want to prevent it.
This call tells the GUI element (your TextBox) that "I did all the checks for this event (i.e. KeyDown event), and I don't want you to contribute in handling of this event (i.e. normally the TextBox would try to add this character to its Text property, but you prevent it)".
Check out documentation on KeyEventArgs.Handled.
KeyPress event enables you to prevent any further changes in the TextBox.
You can do that thanks to Handled property of KeyPressEventArgs
private void UserInputText_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '+')
{
UserInputText.Clear();
e.Handled = true;
}
}
So what im looking to do is find if i have the space bar pressed at all and while it is i would like to have the space bar be released and then pressed again mutiple times with a delay of about 10 ms. i have tried to read and understand this link (https://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress.aspx) but it is still confusing any help? im brand new to c# but i have some experience with pascal of which i have found very similar
(using visual studio 2015 due to my computer not allowing me to update to windows 8.1)
10ms delay mean 100 times per second, no one could do it.
Key events occur in the following order:
KeyDown
KeyPress
KeyUp
Events KeyDown and KeyUp use KeyEventArgs, while KeyPress is KeyPressEventArgs,
KeyEventArgs could details how many keys are pressed at same time. KeyEventArgs.KeyCode is Keys which is a [Flags] enum, it could contains multiple keys, like CTRL+SHift+F+G
if your hotkey is Ctrl+Shift+Space, you can check with:
var hotkeyPressed = e.Control && e.Shift && e.KeyCode == Keys.Space;
if your hotkey is Ctrl+F10+Space, you can check with:
var hotkeyPressed = e.Control && e.KeyCode == (Keys.Space | Keys.F10);
but do not use:
var hotkeyPressed = e.Control && e.KeyCode.HasFlag(Keys.F10) && e.KeyCode.HasFlag(Keys.Space); // e.KeyCode probably contains other flags
KeyPressEventArgs.KeyChar is a string, take a look source code, focus on its comments
[ComVisible(true)]
public class KeyPressEventArgs : EventArgs
{
...
/// <summary>Gets or sets the character corresponding to the key pressed.</summary>
/// <returns>The ASCII character that is composed. For example, if the user presses SHIFT + K, this property returns an uppercase K.</returns>
public char KeyChar { get; set; }
...
}
to use which event, it depends on your requirement.
here is sample code in KeyDown:
private int counting = 0, limit = 10;
private void txt_KeyDown(object sender, KeyEventArgs e)
{
if (!e.KeyCode.HasFlag(Keys.Space)) //check if your expected key is pressed
{
counting = 0;
return;
}
//start counting
counting++;
if (counting > limit)
{
e.Handled = true;
//do you business work, like: Send something somewhere
}
else
{
//do something else, like: show the number 'counting' in GUI
}
}
if you want limit timespan with next space, use a Timer
private void txt_KeyDown(object sender, KeyEventArgs e)
{
timer1.Stop();
if (!e.KeyCode.HasFlag(Keys.Space))
{
counting = 0;
return;
}
//start counting
timer1.Start();
counting++;
if (counting > limit)
{
e.Handled = true;
//do you business work, like: Send something somewhere
}
else
{
//do something else, like: show the number 'counting' in GUI
}
}
//timer1.Interval = 100; //100ms timeout. user has to press space again within 100ms
private void timer1_Tick(object sender, EventArgs e)
{
counting = 0;
}
I have made a Windows Form application with a textbox which uses Barcode scanner to get any input value. I want user to use only Barcode Scanner to fill any value in it, and don't want to enter any input using my regular keyboard.
Since my Barcode works mimics as a keyboard, so disabling my regular keyboard will also disable my Barcode scanner to work.
I've searched manywhere to implement this, and found few answers were suggesting to add a Stopwatch/Timer to eliminiate all keypress which occurs within 50milliseconds, since Barcode can scan all values within 50 milliseconds, but no human can type faster than 50 miliseconds.
I also tried this way, but this fails when I randomly punches my fingers on keyboard keys, it reads out since some of keys fired within 50miliseconds.
Also tried below code but even this does not work as expected for me
private void rtBoxInput_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
}
Please suggest some good way to implement this?
The basic idea is to check:
if KeyUp and KeyDown events are fired of same keys and within specified time (say 17milliseconds), as this can be only done using Barcode scanner.
No one can trigger KeyDown and KeyUp event of same key within 17 milliseconds. For example it will take more than specified time for someone to Press and Release same key, however he can hit punch to keyboard that will push multiple keys all together and trigger their KeyDown and KeyUp events, but all no keys will have KeyUp and KeyDown events fired synchronously. So by this way you can detect whether input made by regular keyboard or barcode scanner.
Please have a look below:
public partial class BarcodeReader : Form
{
char cforKeyDown = '\0';
int _lastKeystroke = DateTime.Now.Millisecond;
List<char> _barcode = new List<char>(1);
bool UseKeyboard = false;
public BarcodeReader()
{
InitializeComponent();
}
private void BarcodeReader_Load(object sender, EventArgs e)
{
this.KeyDown += new KeyEventHandler(BarcodeReader_KeyDown);
this.KeyUp += new KeyEventHandler(BarcodeReader_KeyUp);
}
private void BarcodeReader_KeyUp(object sender, KeyEventArgs e)
{
// if keyboard input is allowed to read
if (UseKeyboard && e.KeyData != Keys.Enter)
{
MessageBox.Show(e.KeyData.ToString());
}
/* check if keydown and keyup is not different
* and keydown event is not fired again before the keyup event fired for the same key
* and keydown is not null
* Barcode never fired keydown event more than 1 time before the same key fired keyup event
* Barcode generally finishes all events (like keydown > keypress > keyup) of single key at a time, if two different keys are pressed then it is with keyboard
*/
if (cforKeyDown != (char)e.KeyCode || cforKeyDown == '\0')
{
cforKeyDown = '\0';
_barcode.Clear();
return;
}
// getting the time difference between 2 keys
int elapsed = (DateTime.Now.Millisecond - _lastKeystroke);
/*
* Barcode scanner usually takes less than 17 milliseconds as per my Barcode reader to read , increase this if neccessary of your barcode scanner is slower
* also assuming human can not type faster than 17 milliseconds
*/
if (elapsed > 17)
_barcode.Clear();
// Do not push in array if Enter/Return is pressed, since it is not any Character that need to be read
if (e.KeyCode != Keys.Return)
{
_barcode.Add((char)e.KeyData);
}
// Barcode scanner hits Enter/Return after reading barcode
if (e.KeyCode == Keys.Return && _barcode.Count > 0)
{
string BarCodeData = new String(_barcode.ToArray());
if (!UseKeyboard)
MessageBox.Show(String.Format("{0}", BarCodeData));
_barcode.Clear();
}
// update the last key press strock time
_lastKeystroke = DateTime.Now.Millisecond;
}
private void BarcodeReader_KeyDown(object sender, KeyEventArgs e)
{
//Debug.WriteLine("BarcodeReader_KeyDown : " + (char)e.KeyCode);
cforKeyDown = (char)e.KeyCode;
}
}
Check Here.. GitHub Link
If your barcode mimics a keyboard - there is no way you can find which one is inputing text in your TextBox. Can your barcode scaner add some prefix to scanned code? If yes - I think this is a best option in combination with 50ms timer.
What you can do is to handle your Barcode directly on your form using a KeyPress Event and disable your TextBox :
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
barcode = string.Empty;
try
{
barcode += e.KeyChar;
if (lastTime > new DateTime())
{
if (DateTime.Now.Subtract(lastTime).Milliseconds > 30)
{
f1 = false;
}
else
{
f1 = true;
}
}
lastTime = DateTime.Now;
/*
Test your Barcode, and if it matches your criteria then change your TextBox text
TextBox1.Text = barcode;
*/
}
catch (Exception ex)
{
MessageBox.Show("Something went wrong");
}
}
Don't forgot to set Form1.KeyPreview = true and it should do the trick !
I have this procedure wich moves the cursor to the next textbox up/down within non multiline textbox.
When using key down from multiline textbox, cursor moves to the next textbox but does not focus in the next textbox when pressing key up idem. With key enter it moves from multiline to the next textbox and focuses it.
What can be the reason ?
I have 8 textboxes which are groupped with tag properties from 0 to 7. TxtboxNbrLimit is set to 8
private void textBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Down)
{
if (KeyIndex < TxtboxNbrLimit)
++KeyIndex;
if (KeyIndex == TxtboxNbrLimit)
{
SaveBtn.Select();
return;
}
if (_textBox[KeyIndex].Text != "")
ChangeDone = true;
_textBox[KeyIndex].SelectionStart = 0;
_textBox[KeyIndex].SelectionLength = _textBox[KeyIndex].Text.Length;
_textBox[KeyIndex].Select();
_textBox[KeyIndex].Focus();
}
else
{
if (e.KeyCode == Keys.Up)
{
if (KeyIndex > 0)
--KeyIndex;
_textBox[KeyIndex].SelectionStart = 0;
_textBox[KeyIndex].SelectionLength = _textBox[KeyIndex].Text.Length;
_textBox[KeyIndex].Select();
_textBox[KeyIndex].Focus();
}
}
}
Try to move your logic to key up event instead of key down. That will work fine, TESTED.
Maybe multiline TextBox has some kind of event handler internally to handle up/down keyboard key pressed event, to move cursor between text lines. So your code work will be overridden by that internal behavior.
And in case you put it in key up event, the opposite happened. Your code logic will override effect of TextBox's internal behavior. So if the TextBox contains multiline text, the cursor will move to next/previous TextBox instead of moving between text lines inside the multiline TextBox.
I have a textbox and want user can not enter space in first textbox.the user can enter space in any where textbox apart of Beginning textbox.my computer = allow my computer = not allow (space in begining) , space maybe one or two or more.
If you really insist on doing this using one of the Events I would suggest you do it in the Text_Changed Event I have set you a simple way to do it..
private void txtaddgroup_TextChanged(object sender, EventArgs e)
{
var textBox = (TextBox)sender;
if (textBox.Text.StartsWith(" "))
{
MessageBox.Show("Can not have spaces in the First Position");
}
}
Implement a keypress event where you get rid of any spaces, read more here.
Add this bit of code to your KeyDown event handler to stop the space key ever being registered:
//Check to see if the first character is a space
if (UsernameTextBox.SelectionStart == 0) //This is the first character
{
//Now check to see if the key pressed is a space
if (e.KeyValue == 32)
{
//Stop the key registering
e.Handled = true;
e.SuppressKeyPress = true;
}
}
32 if the Key Code for the space character.
You should call this function with parameter as 'e' on KeyPress event:
Here 32 is the ASCII value of space
void SpaceValidation(KeyPressEventArgs e)
{
if (e.KeyChar == 32 && ActiveControl.Text.Length == 0)
e.Handled = true;
}
private void textbox1_KeyPress(object sender, KeyPressEventArgs e)
{
SpaceValidation(e);
}