2010-03-02 48 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

相關問題