2010-03-02 78 views

回答

14

有点晚了,但我想出了这个代码,它将重新启动一个计时器上的任何输入事件:

public partial class Window1 : Window { 
    DispatcherTimer mIdle; 
    private const long cIdleSeconds = 3; 
    public Window1() { 
     InitializeComponent(); 
     InputManager.Current.PreProcessInput += Idle_PreProcessInput; 
     mIdle = new DispatcherTimer(); 
     mIdle.Interval = new TimeSpan(cIdleSeconds * 1000 * 10000); 
     mIdle.IsEnabled = true; 
     mIdle.Tick += Idle_Tick; 
    } 

    void Idle_Tick(object sender, EventArgs e) { 
     this.Close(); 
    } 

    void Idle_PreProcessInput(object sender, PreProcessInputEventArgs e) { 
     mIdle.IsEnabled = false; 
     mIdle.IsEnabled = true; 
    } 
    } 
+0

最近我发现了一个问题:当文本框聚焦并且鼠标悬浮在窗口上时,PreProcessInput事件不断发射。当您将鼠标移动到窗口外或将焦点从文本框移开时,它可以正常工作。这是我做错了什么吗? – PVitt 2010-07-29 09:22:16

+0

仅供参考:我试过你的解决方案,并且无法准确理解何时引发'PreProcessInput'事件。你可以在这里找到我的问题:http://stackoverflow.com/questions/4963135/wpf-inactivity-and-activity – 2011-02-11 13:14:35

+0

@Martin,我不知道,WPF对象模型太复杂了。我认为你必须通过PreProcessInputEventArgs对象和转储信息来了解它来自哪里。然后你也可以过滤它。 – 2011-02-11 13:28:37

1

你需要定义“活动”,但基本上你想启动一个计时器。然后每当有一些“活动”时(无论是鼠标点击还是鼠标移动等),计时器都会被重置。

然后在计时器达到您的限制时只需发布一个事件来调用应用程序关闭方法。

+0

活动包括在前台/后台线程应用程序进行用户交互和操作。 – Raj 2010-03-02 12:53:12

+1

@Raj - 如果您需要记录操作,那么您可能需要查看面向方面的方法,在该方法中,您在进入和退出所有可重置计时器的操作方法时触发事件。 – ChrisF 2010-03-02 12:55:59

1

msdn social有关于此事的讨论。检查它,请张贴的内容为你所做的工作....

我粘贴从讨论的代码(一个我认为它会做你的需要):

public partial class Window1 : Window 
{ 
    private EventHandler handler; 
    public Window1() 
    { 
     InitializeComponent(); 

     handler = delegate 
     { 
      DispatcherTimer timer = new DispatcherTimer(); 
      timer.Interval = TimeSpan.FromSeconds(4); 
      timer.Tick += delegate 
      { 
       if (timer != null) 
       { 
        timer.Stop(); 
        timer = null; 
        System.Windows.Interop.ComponentDispatcher.ThreadIdle -= handler; 
        MessageBox.Show("You get caught!"); 
        System.Windows.Interop.ComponentDispatcher.ThreadIdle += handler; 
       } 

      }; 

      timer.Start(); 

      //System.Windows.Interop.ComponentDispatcher.ThreadIdle -= handler; 
      Dispatcher.CurrentDispatcher.Hooks.OperationPosted += delegate 
      { 
       if (timer != null) 
       { 
        timer.Stop(); 
        timer = null; 
       } 
      }; 
     }; 

     ComponentDispatcher.ThreadIdle += handler; 
    } 
} 
+1

ComponentDispatcher.ThreadIdle正在被正确触发,但Dispatcher.CurrentDispatcher.Hooks.OperationPosted正在抽取事件,即使我最小化实质上停止计时器的Window。 – Raj 2010-03-02 13:27:50

0
public MainWindow() 
    { 
     InitializeComponent(); 
     var timer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(10)}; 
     timer.Tick += delegate 
     { 
      timer.Stop(); 
      MessageBox.Show("Logoff trigger"); 
      timer.Start(); 
     }; 
     timer.Start(); 
     InputManager.Current.PostProcessInput += delegate(object s, ProcessInputEventArgs r) 
     { 
      if (r.StagingItem.Input is MouseButtonEventArgs || r.StagingItem.Input is KeyEventArgs) 
       timer.Interval = TimeSpan.FromSeconds(10); 
     }; 
    } 
+0

如果要在某些预处理后启用自动注销事件,请将此代码行保留在主窗口构造函数或表单加载事件中。 – sam 2014-08-26 22:52:19

相关问题