2012-01-25 33 views
2

当用户做了一些事情(在这种情况下触摸一个StackPanel),我需要开始某种计时器(可能是DispatcherTimer,因为我在WPF中工作),并且如果在一定时间内再次发生另一次触摸然后我会调用一个方法。正如你可能猜到的 - 这是为了实现双击功能。如何使用线程'勾选'要被其他线程访问的定时器?

我假设实现这一目标的最佳途径是通过使用线程(即子线程递增可以由主线程的StackPanel被再次触摸随时检查时间跨度?)

谢谢,

回答

6

您不需要启动另一个线程来执行此操作。

只需记下第一次敲击的时间戳并使用它。然后,您可以通过从当前时间减去这个时间计算时间跨度:

private DateTime _lastTap; 
public void TapHandler() 
{ 
    DateTime now = DateTime.UtcNow; 
    TimeSpan span = now - lastTap; 
    _lastTap = now; 
    if (span < TimeSpan.FromSeconds(1)) {...} 
} 

另外,通过@DannyVarod的建议,您可以使用Stopwatch来达到同样的效果(但有更准确的计时):

private Stopwatch _stopwatch = new Stopwatch(); 
public void TapHandler() 
{ 
    TimeSpan elapsed = _stopwatch.Elapsed; 
    _stopwatch.Restart(); 
    if (elapsed < TimeSpan.FromSeconds(1)) {...} 
} 
+1

并且不应该需要线程。 – nos

+0

完美。发现。对我来说,一定是早上太早了。给我10分钟,我会将其标记为答案。 –

+0

准确地说,我要回答(虽然没有代码示例)。 – Nuffin

1

最好的办法是坚持DispatcherTimer,你首先指出,因为这将确保您不会需要做剔任何线程编组。如果您明确需要准确性和/或后台线程,请参阅System.Timers.Timer类和System.Threading.Timer类。

允许区分单击和双击的代码示例可在MSDN(特定于Windows窗体,但原理相同)上找到。或者,请参阅此示例使用DispatcherTimer取自this previous question

private static DispatcherTimer clickTimer = 
     new DispatcherTimer(
      TimeSpan.FromMilliseconds(SystemInformation.DoubleClickTime), 
      DispatcherPriority.Background, 
      mouseWaitTimer_Tick, 
      Dispatcher.CurrentDispatcher); 

    private void Button_MouseDoubleClick(object sender, MouseButtonEventArgs e) 
    { 
     // Stop the timer from ticking. 
     myClickWaitTimer.Stop(); 

     Trace.WriteLine("Double Click"); 
     e.Handled = true; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     myClickWaitTimer.Start(); 
    } 

    private static void mouseWaitTimer_Tick(object sender, EventArgs e) 
    { 
     myClickWaitTimer.Stop(); 

     // Handle Single Click Actions 
     Trace.WriteLine("Single Click"); 
    }