WPF如何有效检测用户活动

Pat*_*ick 3 c# wpf events android-activity

我有一个应用程序,在其中 x 秒不活动后我必须注销。因此,我有一个计时器正在运行,并根据上次重置的用户活动计算时间跨度:

dtLastActivity = DateTime.Now;
Run Code Online (Sandbox Code Playgroud)

所以问题是,我认为这不是将程序中的每个事件与上述代码相关联的最佳方法。但最终我不需要每个事件:所有有用的就是跟踪 KEYPRESS 和 MOUSEUP。

在主窗口中跟踪这两个事件是否正确?

我必须承认,我仍然没有付诸实践(但我会),因为我不确定这是否是达到标题目的的最佳方法。

作为 WPF 新手,我也不清楚在主窗口中跟踪键盘和鼠标是否不会影响子级(即实际上是事件目标的控件)的行为。

预先感谢您的任何帮助。

---编辑--- 建议的解决方案非常优雅。特别是这个:

    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,
            };
        }
    }
Run Code Online (Sandbox Code Playgroud)

但这太自动了。我无法控制它。例如,如果我从一开始就使用它,它会在启动之前空闲,因为我的应用程序有一个相当长的启动时间,包括启动屏幕、反序列化等......

Fruchtzwerg 提出的解决方案与我的需求更加相似,因为我可以完全控制它。它还有一个优点,如果我点击另一个应用程序,计时器不会重置!

Fru*_*erg 5

我通常使用你描述的方法。我运行一个计时器并重新启动每次交互。窗口的事件有:

PreviewMouseDown="Window_Action"
PreviewKeyDown="Window_Action"
Run Code Online (Sandbox Code Playgroud)

重新启动计时器:

private void Window_Action(object Sender, InputEventArgs e)
{
  IdleTimer.Stop();
  IdleTimer.Start();
}
Run Code Online (Sandbox Code Playgroud)

从来没有遇到过任何与这种灵魂有关的问题。使用秒表重新启动计时器需要不到 80 个滴答声。所以我认为资源是没有问题的。

您还可以通过在事件中添加术语来指定用户交互。

预览活动不会干扰其他活动。此处描述了这种隧道行为。