2011-04-25 75 views
2

我有一个表格,如果没有鼠标交互完成,我想在5秒后关闭,但如果有任何鼠标交互完成,我希望它关闭countdown + 5 seconds,每次交互会增加5秒。倒数计时器增加交互?

这是我想出了这么远:

int countdown = 5; 
System.Timers.Timer timer; 

启动计时器

timer = new System.Timers.Timer(1000); 
timer.AutoReset = true; 
timer.Elapsed += new System.Timers.ElapsedEventHandler(ProcessTimerEvent); 
timer.Start(); 

事件

private void ProcessTimerEvent(Object obj, System.Timers.ElapsedEventArgs e) 
{ 
    --countdown; 
    if (countdown == 0) 
    { 
     timer.Close(); 
     this.Invoke(new Action(() => { this.Close(); })); 
    } 
} 

而只是为了测试我使用的形式,鼠标点击事件将倒数增加5,但不得不将其更改为不同的事件,因为如果您点击标签或任何其他c在形式上控制它不会增加定时器。

private void NotifierTest_MouseClick(object sender, MouseEventArgs e) 
{ 
    countdown += 5; 
} 

问题

  • 我是否实施倒计时,其中 计数器可以在 正确的方式来增加?

  • 我应该改变什么吗?

  • 如果与我所做的有什么不同,你会怎么做?

  • 我该如何处理鼠标点击 捕获?

  • 使用低级挂钩?

  • 使用鼠标点击位置并验证 如果它是否在我的winform?

其他选项

不同的选项我目前的想法是捕捉鼠标是否表单区域之内还是之外,启用/禁用关闭倒计时,如果它不在范围内,但我不确定如何与鼠标进行交互,因此上述问题将如何与鼠标进行交互。

+0

因此,如果他们快速点击10次,您希望表单在停止点击后保持打开时间为50秒?不知道你为什么要这样做。除非有某种进度条在每次点击时填充更多内容,并随着时间的推移逐渐耗尽,否则我会被视为用户。 – Justin 2011-04-25 13:20:31

+0

@Justin这会发生什么,上面的代码目前这样做,我明白它不是很优雅,但我正在寻找的选项,如果鼠标,如果在形式。那么用户不会知道这一点,它基本上是类似于如果通知出现,用户将看到它,但他只会与它进行交互,如果他们喜欢或需要或发现有趣的东西,沿着这些线。 – Prix 2011-04-25 13:22:40

+2

@Prix,而不是增加'countdown + = 5',你可以使用'countdown = 5'来重置它,它会将其重置为5秒,而不是累积每次鼠标交互。 – 2011-04-25 13:27:42

回答

3

我认为你在做的事情本质上是好的,真正的技巧是处理鼠标事件。

这是一个快速和肮脏的例子,你如何才能做到这一点,只是检查鼠标是否在窗口的客户区。基本上在每个计时器到期时,代码都会在屏幕上获取鼠标位置,并检查是否与窗口的客户区重叠。你应该也可以检查窗口是否激活等,但这应该是一个合理的起点。

using System; 
using System.Windows.Forms; 
using System.Timers; 
using System.Drawing; 

namespace WinFormsAutoClose 
{ 
    public partial class Form1 : Form 
    { 
    int _countDown = 5; 
    System.Timers.Timer _timer; 

    public Form1() 
    { 
     InitializeComponent(); 

     _timer = new System.Timers.Timer(1000); 
     _timer.AutoReset = true; 
     _timer.Elapsed += new ElapsedEventHandler(ProcessTimerEvent); 
     _timer.Start(); 
    } 

    private void ProcessTimerEvent(Object obj, System.Timers.ElapsedEventArgs e) 
    { 
     Invoke(new Action(() => { ProcessTimerEventMarshaled(); })); 
    } 

    private void ProcessTimerEventMarshaled() 
    { 
     if (!IsMouseInWindow()) 
     { 
     --_countDown; 
     if (_countDown == 0) 
     { 
      _timer.Close(); 
      this.Close(); 
     } 
     } 
     else 
     { 
     _countDown = 5; 
     } 
    } 

    private bool IsMouseInWindow() 
    { 
     Point clientPoint = PointToClient(Cursor.Position); 
     return ClientRectangle.Contains(clientPoint); 
    } 
    } 
} 
+0

部分,这是我目前正在尝试做的事情,而不是做一个计时器事件我试图做一个鼠标悬停事件,将启动或不倒计时器的基础上,如果鼠标是在窗体内或不是,但使用Winforms当我将鼠标移出它时,它不会捕获事件,所以我猜测我必须捕获鼠标,我在哪里正确? – Prix 2011-04-25 14:06:35

+0

@Prix,如果窗体上有其他控件,使用MouseOver,MouseEnter,MouseLeave事件可能会产生问题,因为这些控件在某些情况下会在表单获取它们之前吞下鼠标事件。这就是为什么我选择蛮力检查鼠标相对于屏幕上的表单完全独立于窗体上的控件的位置。 – 2011-04-25 14:15:37

+0

是的,我的坏我现在才注意到它,就像一个魅力真的很感谢您的时间和帮助。 – Prix 2011-04-25 14:23:08