3

I have an application in which I have to logout after say x seconds of inactivity. I therefore have a timer going on and calculating a timespan from the last user acitivity resetted with:

dtLastActivity = DateTime.Now;

So the problem is that I don't think it's the best approach to associate EVERY single event in my program with the afore mentioned code. But in the end I don't need EVERY event: all what is useful is to track KEYPRESS and MOUSEUP.

Would it be correct to track those two event in the MainWindow?

I have to admit that I still have not put into practice this (but I will) for I am not sure that this is the best approach for the purpose in the title.

Being new to WPF I am also not clear if tracking keyboard and mouse in the mainwindow shall not affect the behaviour in the children (that are the controls that effectively are the target of the event).

Thank you in advance for any help.

---EDIT--- The proposed solutions are very elegant. Particularly this one:

    public static class IdleTimeDetector
    {
        [DllImport("user32.dll")]
        static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

        public static IdleTimeInfo GetIdleTimeInfo()
        {
            int systemUptime = Environment.TickCount,
                    lastInputTicks = 0,
                    idleTicks = 0;

            LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
            lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
            lastInputInfo.dwTime = 0;

            if (GetLastInputInfo(ref lastInputInfo))
            {
                lastInputTicks = (int)lastInputInfo.dwTime;
                idleTicks = systemUptime - lastInputTicks;
            }

            return new IdleTimeInfo
            {
                LastInputTime = DateTime.Now.AddMilliseconds(-1 * idleTicks),
                IdleTime = new TimeSpan(0, 0, 0, 0, idleTicks),
                SystemUptimeMilliseconds = systemUptime,
            };
        }
    }

but it is too automatic. I have no control over it. E.g. if I use it from the beginning it gets idle BEFORE starting because my application has a quite long start time with splash screen, deserialization etc...

The solution proposed by Fruchtzwerg is much more similar to my needs because I get complete control over it. It has also the advantage that if I click on another application the timer is not resetted!!

Patrick
  • 3,073
  • 2
  • 22
  • 60
  • Possible duplicate of [Idle Detection in WPF](http://stackoverflow.com/questions/23286766/idle-detection-in-wpf); also http://stackoverflow.com/questions/1111615/getting-inactivity-idle-time-in-a-wpf-application – ASh May 01 '16 at 15:30

1 Answers1

5

I usually use the approach described by you. I running a timer and restart every interaction. The events of a window are:

PreviewMouseDown="Window_Action"
PreviewKeyDown="Window_Action"

Restarting the timer:

private void Window_Action(object Sender, InputEventArgs e)
{
  IdleTimer.Stop();
  IdleTimer.Start();
}

Never had any prolmems with this soultion. Restarting the timer takes under 80 ticks with a stopwatch. So the resources are in my opinion no problem.

Also you can specify the userinteractions by adding terms in your event.

The Preview-Events are not disturbing other events. This tunneling-behavoiur is described here.

Fruchtzwerg
  • 10,999
  • 12
  • 40
  • 49
  • Your solution is just what I am searching for. I'd just like to know if you are confident that grabbing those events in the mainWindow doesn't affect children events in any way. – Patrick May 01 '16 at 20:48