0

I have a function to detect a textfield to recognize a barcode scanner input or human input in my winform application:

    DateTime lastKeyPress = DateTime.Now;
    private void searchContent_TextChanged(object sender, EventArgs e)
    {
        TimeSpan elapsed = (DateTime.Now - lastKeyPress);
        if (elapsed.TotalMilliseconds > 10)
        {
            cartBarcode.Text = "not barcode";
        }
        else
        {
            cartBarcode.Text = "is barcode";
            //after the last character was printed 
            addBarcodeProductToCart ();
        }

        lastKeyPress = DateTime.Now;

    }

    private void addBarcodeProductToCart ()
    {
        cartGridView.Rows[0].Selected = true;
    }

The problem of above is that after 2 characters was printed, addBarcodeProductToCart is already executed. How to detect last character was typed in above function?

hkguile
  • 4,235
  • 17
  • 68
  • 139
  • why not kick off a task every keypress with a delay of 2 seconds. cancel the previous task every keypress when the task is executed it calls your add function – Mark May 25 '17 at 10:14
  • "How can I detect whether some other piece of code is planning to perform some further activity in the near future or not?" Doesn't really seem directly solvable. You could set some form of timeout but I'd generally look in the manual and see if the scanner has an option for it to include leading and trailing "special" characters which would be far better than developing time-based heuristics. – Damien_The_Unbeliever May 25 '17 at 10:14
  • why the criteria is 10 ms? and human types faster than barcode reader? – kennyzx May 25 '17 at 10:17
  • The first thing you need to do is precisely specify in english (or any other language - not in code is the point) what the criteria is for adding the product to the cart. If you were looking at the screen what criteria would you use to decide if the last character had been added? Once you have established that (and I assume you haven't since that spec isn't in the question) then you can work on converting that to code. There are a few ways you could determine if it is the last character. Barcodes are usually a standard length. Or maybe just no input in the last 5 seconds means its done... – Chris May 25 '17 at 10:17

1 Answers1

0

As per my main comment. Why not delay for a second or two? however detecting a barcode is typically done by calculating the check digit How do I validate a UPC or EAN code?

private CancelationTokenSource _cancellationTokenSource= new CancelationTokenSource();

    private void searchContent_TextChanged(object sender, EventArgs e)
    {

            Task.Run(async () =>
                {

                    _cancellationTokenSource.Cancel();
                    _cancellationTokenSource = new CancellationTokenSource();
                    var token = _cancellationTokenSource.Token;

                    try
                    {
                        await Task.Delay(TimeSpan.FromSeconds(TimeSpan.FromSeconds(2), token).ContinueWith(r =>
                        {
                            if (!token.IsCancellationRequested)
                            {
                                addBarcodeProductToCart ();
                            }
                        }, token);
                    }
                    catch (TaskCanceledException e)
                    {
                        //noop
                    }
                }).ConfigureAwait(false);



}
Mark
  • 1,544
  • 1
  • 14
  • 26
  • thx for answer, but i use DataBindingComplete solved my problem, its much simpler private void pproductGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e) { if (isBarcode == true) { MessageBox.Show("barcode detected"); pproductGridView.Rows[0].Selected = true; } } – hkguile May 25 '17 at 10:37