2010-03-02 10 views

Répondre

14

Un peu en retard, mais je suis venu avec ce code, il redémarre une minuterie sur un événement d'entrée:

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

Il y a un problème que j'ai trouvé récemment: Lorsqu'une zone de texte est mise au point et que la souris survole la fenêtre, l'événement PreProcessInput déclenche constamment. Lorsque vous déplacez la souris en dehors de la fenêtre ou que vous désactivez la zone de texte, cela fonctionne correctement. Est-ce que c'est moi qui fais quelque chose de mal? – PVitt

+0

FYI: J'ai essayé votre solution et j'ai du mal à comprendre exactement quand l'événement 'PreProcessInput' est déclenché. Vous pouvez trouver ma question ici: http://stackoverflow.com/questions/4963135/wpf-inactivity-and-activity –

+0

@ Martin, je ne sais pas, le modèle d'objet WPF est beaucoup trop compliqué. Je pense que vous devrez explorer l'objet PreProcessInputEventArgs et récupérer des informations pour savoir d'où cela vient. Vous avez également une chance de le filtrer. –

1

Vous aurez besoin de définir «activité», mais vous voulez démarrer une minuterie. Ensuite, chaque fois qu'il y a une "activité" (qu'il s'agisse de clics de souris ou de mouvements de souris, etc.), la minuterie est réinitialisée. Puis dans le temporisateur lorsqu'il atteint votre limite, envoyez un événement pour appeler la méthode de fermeture de l'application.

+0

Les activités comprennent l'interaction utilisateur et le fonctionnement fait par application en fil de premier plan/arrière-plan. – Raj

+1

@Raj - si vous avez besoin d'enregistrer des opérations, vous pouvez envisager une approche orientée aspect où vous déclenchez un événement à l'entrée et à la sortie de toutes les méthodes opérationnelles qui réinitialiseraient le temporisateur. – ChrisF

1

Il y avait une discussion dans msdn social à ce sujet. Vérifiez et s'il vous plaît poster ce qui ne fonctionne pour vous ....

Je vous collez le code de la discussion (celui que je pense que ça va faire ce que vous avez besoin):

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 se déclenche correctement, mais Dispatcher.CurrentDispatcher.Hooks.OperationPosted pompe des événements même si je minimise la fenêtre qui arrête essentiellement le minuteur. – Raj

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

Conservez cette ligne de code dans le constructeur de votre fenêtre principale ou dans l'événement de chargement de formulaire si vous souhaitez activer l'événement de déconnexion automatique après un prétraitement. – sam

Questions connexes