C# – WPF DispatcherTimer and Mouse Button Click Timing

cnetwpf

Consider the following code, I have a textblock that is an "on/off" button in WPF. It's just text inside an ellipse that says ON / OFF. When the user clicks the button and holds the left mouse for ONE second, it will execute the 'turn device on' code if the device is not already powered up. If the user holds the ON/OFF button for three seconds or more (keeps left mouse button HELD down) the device will turn off.

Several problems that I'm missing the boat on.
1. The tick event is not firing while the mouse button is held down, despite the fact the timer is started.
2. The do/while loop never exits despite lifting the button

Thanks!

    public int TimerCount = 0;

    private void ButtonPressTimer(object sender, EventArgs e)
    {
        TimerCount = TimerCount + 1;
    }

    private void txtBlockOnOff_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var buttonPressTimer = new DispatcherTimer(new TimeSpan(0, 0, 0, 1), DispatcherPriority.Normal, ButtonPressTimer, this.Dispatcher);

        do
        {
            if (!buttonPressTimer.IsEnabled)
                buttonPressTimer.Start();
        }
        while (e.ButtonState == MouseButtonState.Pressed);

        buttonPressTimer.Stop();
        if (TimerCount >= 3)
        {
            //do something here
        }
        else
        { 
            //do something different here
        }
    }

Best Answer

I'd look at a slightly different approach that doesn't require the overhead of setting up a timer. If you handle both the mouse down and up events, and store the time when the button was pressed, you can compare it to the time when the mouse is released and decide what to do.

private DateTime mousePressed;

private void txtBlockOnOff_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    mousePressed = DateTime.Now;
}

private void txtBlockOnOff_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    // button released

    TimeSpan difference = DateTime.Now - mousePressed;

    if (difference.TotalSeconds >= 3)
    {
        // long press
    }
    else
    {
        // short press
    }
}
Related Topic