定时器触发事件 WPF

3
我这里有一个项目,该项目默认通过MouseEnter事件来触发操作。我的意思是,打开窗口、关闭窗口、返回等等,都只能通过MouseEnter事件来完成。
我被要求让事件在3秒后才触发。这意味着用户将鼠标放在控件上,直到3秒后所有窗口中的控件才会触发事件。
所以,我想到了一个全局计时器或类似的东西,它会返回false,直到计时器达到3...我认为这是正确的方法...
天啊,有人知道我怎么做这种事吗?
谢谢!

你不能在MouseEnter事件中睡眠3秒钟吗? - paparazzo
1
在 MouseEnter 事件中休眠 3 秒将会锁定用户界面 3 秒钟。 - Wonko the Sane
2个回答

7
您可以定义一个类,该类将公开一个DelayedExecute方法,该方法接收要执行的操作并根据需要创建计时器以进行延迟执行。它看起来会像这样:
public static class DelayedExecutionService
{
    // We keep a static list of timers because if we only declare the timers
    // in the scope of the method, they might be garbage collected prematurely.
    private static IList<DispatcherTimer> timers = new List<DispatcherTimer>();

    public static void DelayedExecute(Action action, int delay = 3)
    {
        var dispatcherTimer = new System.Windows.Threading.DispatcherTimer();

        // Add the timer to the list to avoid it being garbage collected
        // after we exit the scope of the method.
        timers.Add(dispatcherTimer);

        EventHandler handler = null;
        handler = (sender, e) =>
        {
            // Stop the timer so it won't keep executing every X seconds
            // and also avoid keeping the handler in memory.
            dispatcherTimer.Tick -= handler;
            dispatcherTimer.Stop();

            // The timer is no longer used and shouldn't be kept in memory.
            timers.Remove(dispatcherTimer);

            // Perform the action.
            action();
        };

        dispatcherTimer.Tick += handler;
        dispatcherTimer.Interval = TimeSpan.FromSeconds(delay);
        dispatcherTimer.Start();
    }
}

那么你可以这样调用它:
DelayedExecutionService.DelayedExecute(() => MessageBox.Show("Hello!"));

或者

DelayedExecutionService.DelayedExecute(() => 
{
    DoSomething();
    DoSomethingElse();
});

当然,@AdiLester,我也更新了我的代码!这段代码在这里节省了很多时间!非常感谢! - Armando Freire
@StefanVasiljevic 在这种情况下,您可以注册到Storyboard的“Completed”事件,并在那里执行您的逻辑。 - Adi Lester
@StefanVasiljevic 是的。谷歌“Completed”事件 - 我相信你会找到很多例子。 - Adi Lester
我想要延迟事件在一次运行中每次被调用的触发时间3秒钟。 - Little Programmer
@LittleProgrammer 你可能正在寻找延迟绑定:http://www.jonathanantoine.com/2011/09/21/wpf-4-5-part-4-the-new-bindings-delay-property/ - Adi Lester
显示剩余6条评论

1
我只想添加一个更简单的解决方案:
public static void DelayedExecute(Action action, int delay = 3000)
{
    Task.Factory.StartNew(() => 
    {
        Thread.Sleep(delay);
        action();
    }
}

然后就像在另一个答案中一样使用它。


的确更简单,但我认为应尽可能避免使用 Sleep - Adi Lester
@AdiLester,你能否请评论一下为什么? - Louis Kottmann
1
本文指出了几个原因:http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx - Adi Lester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接