4

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");
}
4

2 に答える 2

7

すべての MouseMove イベントで新しいタイマーを作成する必要はありません。停止して再起動するだけです。また、一度だけ起動する必要があるため、Tick ハンドラーで停止されていることを確認してください。

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();
}
于 2012-11-04T08:20:51.023 に答える
6

このように再度フックする前にunhook必要です-event

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();
}

説明

あなたがしていることは、マウスが動くたびに、 DispatcherTimer の新しいインスタンスを作成し、 なしで Tick イベントをそれにフックすることunhooking the event for previous instanceです。したがって、すべてのインスタンスのタイマーが停止すると、大量のメッセージが表示されます。

また、フックを解除する必要があります。そうしないと、以前のインスタンスgarbage collectedはまだstrongly referenced.

于 2012-11-04T07:41:44.333 に答える