I have a barcode scanner that emulates keyboard entry. I'm using it to enter ISBN numbers into a textbox, which then performs a search for that title. I need the textbox method to wait for wither a 10 or 13 character entry before doing anything, however I'm not sure how to go about doing it.
So far, I have the following:
private void scanBox_TextChanged(object sender, EventArgs e)
{
if (scanBox.Text.Length == 10)
{
getRecord10();
}
else if (scanBox.Text.Length == 13)
{
getRecord13();
}
else
{
MessageBox.Show("Not in directory", "Error");
}
}
I'm considering some sort of timer implementation to hold off on that last condition, but what I really need is for the method to wait for either 10 or 13 digits. The barcode scanner emulates individual keys being pressed, which is why it is currently failing.
You can use Timer (or DispatcherTimer in WPF). This sample app updates window's title 300ms after the last keystroke.
System.Windows.Forms.Timer _typingTimer; // WinForms
// System.Windows.Threading.DispatcherTimer _typingTimer; // WPF
public MainWindow()
{
InitializeComponent();
}
private void scanBox_TextChanged(object sender, EventArgs e)
{
if (_typingTimer == null)
{
/* WinForms: */
_typingTimer = new Timer();
_typingTimer.Interval = 300;
/* WPF:
_typingTimer = new DispatcherTimer();
_typingTimer.Interval = TimeSpan.FromMilliseconds(300);
*/
_typingTimer.Tick += new EventHandler(this.handleTypingTimerTimeout);
}
_typingTimer.Stop(); // Resets the timer
_typingTimer.Tag = (sender as TextBox).Text; // This should be done with EventArgs
_typingTimer.Start();
}
private void handleTypingTimerTimeout(object sender, EventArgs e)
{
var timer = sender as Timer; // WinForms
// var timer = sender as DispatcherTimer; // WPF
if (timer == null)
{
return;
}
// Testing - updates window title
var isbn = timer.Tag.ToString();
windowFrame.Text = isbn; // WinForms
// windowFrame.Title = isbn; // WPF
// The timer must be stopped! We want to act only once per keystroke.
timer.Stop();
}
Parts of code are taken from the Roslyn syntax visualizer
I propose a solution using Microsoft Reactive Extensions which are available as a nuget package.
Reactive Extensions is a library to compose asynchronous and event-based programs using observable collections and LINQ-style query operators.
If you use the RX extensions your problem can be solved with just two lines of code:
Sign up for an event: here with count == 10
IObservable<string> textChangedObservable =
Observable.FromEventPattern(textBox1, "TextChanged")
.Select(evt => ((TextBox)evt.Sender).Text).Where(x => x.Length == 10);
Subscribe to the Event:
textChangedObservable.Subscribe(e => MessageBox.Show(e));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With