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 提出的解决方案与我的需求更加相似,因为我可以完全控制它。它还有一个优点,如果我点击另一个应用程序,计时器不会重置!
我通常使用你描述的方法。我运行一个计时器并重新启动每次交互。窗口的事件有:
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 个滴答声。所以我认为资源是没有问题的。
您还可以通过在事件中添加术语来指定用户交互。
预览活动不会干扰其他活动。此处描述了这种隧道行为。