For example, if the button contained the digit 2, as well as the letters ABC, clicking a button for the first time causes the first letter of the sequence to be added to a string (A). Rapid clicking should advance within the sequence (i.e., two clicks causes the second letter to be entered [B], three clicks causes the 3 letter [C]). After reaching the end of the sequence, the sequence restarts (A). Selecting a letter from a sequence must be completed within one second, otherwise the sequence restarts (A).
What I cannot work out is the code required to measure the time in between clicks and the function description to indicate a button has been clicked more than once or multiple times. Can you help me figure this out?
I know the exact functionality you are talking about. My cell phone has the same behavior when I enter names in its phone book. I'll assume your application is a Windows Forms application (or not a Web application or Web service). Each button will need to have associated with it an array of values (call it m_valArray) and an index (m_curIndex) to the current value (initially 0). Each button will also have associated with it a System.Timers.Timer object (m_resetTimer) that has its Interval property set to 1000 ms. The timer will also call a method on the button called ResetIndex when 1000 ms has elapsed. You won't start the timer yet, though. The timer's AutoReset property should be false (you only want a single callback to be issued for each call to the Timer's Start method).
Now, each time the button is pressed, you simply increment m_curIndex modulo the number of values in m_valArray. Then you'll perform the button's corresponding "function" based on m_valArray[m_curIndex]. Afterward, you'll also call the timer's Stop method in case it's been started and restart the timer using the Start method. Whenever ResetIndex is called, you'll simply reset m_curIndex to 0. Since ResetIndex will be called from a separate thread, you'll want to protect m_curIndex and the easiest way to do that is to declare it as volatile in C#. In VB.NET there is no equivalent for volatile, so you'll have to protect m_curIndex explicitly and in VB.NET the easiest way to do that would be to use the System.Threading.Interlocked class's static Exchange method (and use its static Increment method when the button is clicked).
That's pretty much it. Each time the button is pressed, it will cycle to the next value (using your example, "A" to "B" to "C" back to "A" etc.). If ever a second transpires between presses, the button resets to the first value ("A" in your example). Each time the button is pressed, the clock restarts and the user is given one more second. Q.E.D.
This was first published in May 2004