2

I have a winform application and on the main form I placed a textbox.

What I want is that on the OnTextChanged event I need to query sql (stored proc) table in order to bring a list of matches with the character typed. For example if I type letter A then automaticly I should go and search in the database for names starting with letter "A", if I then type letter "L" then I should go and search for names starting with "AL" and so on.

The thing is that If I the user type fast then It should cancel any async process that is in progress and keep only the task for the last letter typed.

Any clue on how to achieve these?

svick
  • 236,525
  • 50
  • 385
  • 514
VAAA
  • 14,531
  • 28
  • 130
  • 253

1 Answers1

2

The thing is that If I the user type fast then It should cancel any async process It shouldn't need to cancel anything - the trick is not to start anything until you think the user has stopped typing.

I wrote something a bit similar, whereby when the user typed I had a thread start a new method, the method waited for a (configurable) time before executing. Another keystroke would call the method again and reset the wait period - effectively if someone continued to type the task wouldn't execute; as soon as they stopped it would (after a 200 ms pause for example).

I would implement something similar if I were you, as it avoids going to SQL when you don't have to

updated - by way of a simple example, a new project with a new form and default text box should allow the following code to function for your needs (as a very simple starting point)

 public partial class Form1 : Form
    {
        private bool _waiting;
        private bool _keyPressed;
        private const int TypingDelay = 220; // ms used for delay between keystrokes to initiate search

        public Form1()
        {
            InitializeComponent();
        }

        private void WaitWhileUserTyping()
        {
            var keepWaiting = true;

            while (keepWaiting)
            {
                _keyPressed = false;

                Thread.Sleep(TypingDelay);

                keepWaiting = _keyPressed;
            }

            Invoke((MethodInvoker)(ExecuteSearch));

            _waiting = false;
        }

        private void ExecuteSearch()
        {
            Thread.Sleep(200); // do lookup

            // show search results...
            MessageBox.Show("Search complete");
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

            if (_waiting)
            {
                _keyPressed = true;
                return;
            }

            _waiting = true;
            // kick off a thread to do the search if nothing happens after x ms
            ThreadPool.QueueUserWorkItem(_ => WaitWhileUserTyping());
        }
    }
NDJ
  • 5,189
  • 1
  • 18
  • 27
  • Amazing nice!! @NDJ do you have example code I can look at? I will appreciate it so much. Thanks – VAAA Oct 04 '13 at 23:39
  • I just post another question with a code someone put here but later remove: http://stackoverflow.com/questions/19192736/c-sharp-winform-async-process-cpu-increases-to-50 – VAAA Oct 05 '13 at 00:37
  • Hi just create another question regarding an issue updating the UI using your code: http://stackoverflow.com/questions/19199251/c-sharp-thread-inside-thread-trying-to-invoke-and-update-ui (by the way your code works nice) Thanks – VAAA Oct 05 '13 at 15:15