ashwnacharya
ashwnacharya

Reputation: 14891

WPF event that triggers after the mouse stops moving

I am writing a WPF application. I want to trigger an event once the mouse stops moving.

This is how I tried to do it. I created a timer which counts down to 5 seconds. This timer is "reset" every time the mouse moves. This idea is that the moment the mouse stops moving, the timer stops being reset, and counts down from 5 to zero, and then calls the tick event handler, which displays a message box.

Well, it doesn't work as expected, and it floods me with alert messages. What am I doing wrong?

DispatcherTimer timer;

private void Window_MouseMove(object sender, MouseEventArgs e)
{
    timer = new DispatcherTimer();
    timer.Interval = new TimeSpan(0, 0, 5);
    timer.Tick += new EventHandler(timer_Tick);
    timer.Start();
}

void timer_Tick(object sender, EventArgs e)
{
    MessageBox.Show("Mouse stopped moving");
}

Upvotes: 4

Views: 3610

Answers (2)

Clemens
Clemens

Reputation: 128147

It is not necessary to create a new timer on every MouseMove event. Just stop and restart it. And also make sure that it is stopped in the Tick handler, since it should be fired only once.

private DispatcherTimer timer;

public MainWindow()
{
    InitializeComponent();

    timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) };
    timer.Tick += timer_Tick;
}

void timer_Tick(object sender, EventArgs e)
{
    timer.Stop();
    MessageBox.Show("Mouse stopped moving");
}

private void Window_MouseMove(object sender, MouseEventArgs e)
{
    timer.Stop();
    timer.Start();
}

Upvotes: 8

Rohit Vats
Rohit Vats

Reputation: 81323

You need to unhook the event before hooking it again like this -

private void poc_MouseMove(object sender, MouseEventArgs e)
{
   if (timer != null)
   {
      timer.Tick-= timer_Tick;
   }
   timer = new DispatcherTimer();
   timer.Interval = new TimeSpan(0, 0, 5);
   timer.Tick += new EventHandler(timer_Tick);
   timer.Start();
}

Explanation

What you doing is whenever a mouse moves, you create a new instance of DispatcherTimer and hook Tick event to it without unhooking the event for previous instance. Hence, you see flooded messages once timer stops for all the instances.

Also, you should unhook it otherwise previous instance won't be garbage collected since they are still strongly referenced.

Upvotes: 6

Related Questions