如果用户闲置一段时间,我想创建一个超时并导航到主页面的函数.经过一番研究,我发现ThreadPoolTimer应该适合我的需要.测试它我决定使用10秒的间隔.
timer =ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick,TimeSpan.FromSeconds(10));
Run Code Online (Sandbox Code Playgroud)
这就是我不知所措的地方.我无法找到一种方法来检查UWP上的用户输入,而无需单独检查PointerPressed,PointerExited等.所以我做了一些挖掘,我找到了一个代码块,如果用户应该给你一个布尔值闲置与否.
public static uint GetIdleTime()
{
LASTINPUTINFO lastInPut = new LASTINPUTINFO();
lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut);
GetLastInputInfo(ref lastInPut);
return ((uint)Environment.TickCount - lastInPut.dwTime);
}
public static bool IsUserIdle()
{
uint idleTime = (uint)Environment.TickCount - GetLastInputEventTickCount();
if (idleTime > 0)
{
idleTime = (idleTime / 1000);
}
else
{
idleTime = 0;
}
//user is idle for 10 sec
bool b = (idleTime >= 10);
return b;
}
private static uint GetLastInputEventTickCount()
{
LASTINPUTINFO lii = new LASTINPUTINFO();
lii.cbSize = (uint)Marshal.SizeOf(lii);
lii.dwTime = 0;
uint p = GetLastInputInfo(ref lii) ? lii.dwTime : 0;
return p;
}
[StructLayout(LayoutKind.Sequential)]
private struct LASTINPUTINFO
{
public static readonly int SizeOf = Marshal.SizeOf<LASTINPUTINFO>();
[MarshalAs(UnmanagedType.U4)]
public UInt32 cbSize;
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwTime;
}
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
Run Code Online (Sandbox Code Playgroud)
然后我在tick函数中调用函数并使用条件语句,如果IsUserIdle()等于true,则导航到主页面.
public static void Timer_Tick(object sender)
{
if (IsUserIdle() == true)
{
Frame.Navigate(typeof(MainPage));
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我开始它没有任何反应时,在我设置了几个断点后,我发现即使在10秒不活动之后,IsUserIdle()也永远不会返回真值.我完全陷入困境,所以任何帮助都会受到赞赏.
Windows应用商店应用不支持GetLastInputInfo:
支持的最低客户端:Windows 2000 Professional [ 仅限桌面应用程序 ]
我不知道有任何内在的UWP API可以检测用户是否处于空闲状态,但是完全可以启动自己的机制.
我无法找到一种方法来检查UWP上的用户输入,而无需单独检查PointerPressed,PointerExited等.
这种方法有什么不好的?这是我的尝试:
App.xaml.cs
public sealed partial class App : Application
{
public static new App Current => (App)Application.Current;
public event EventHandler IsIdleChanged;
private DispatcherTimer idleTimer;
private bool isIdle;
public bool IsIdle
{
get
{
return isIdle;
}
private set
{
if (isIdle != value)
{
isIdle = value;
IsIdleChanged?.Invoke(this, EventArgs.Empty);
}
}
}
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
idleTimer = new DispatcherTimer();
idleTimer.Interval = TimeSpan.FromSeconds(10); // 10s idle delay
idleTimer.Tick += onIdleTimerTick;
Window.Current.CoreWindow.PointerMoved += onCoreWindowPointerMoved;
}
private void onIdleTimerTick(object sender, object e)
{
idleTimer.Stop();
IsIdle = true;
}
private void onCoreWindowPointerMoved(CoreWindow sender, PointerEventArgs args)
{
idleTimer.Stop();
idleTimer.Start();
IsIdle = false;
}
}
Run Code Online (Sandbox Code Playgroud)
MainPage.xaml.cs中
public sealed partial class MainPage : Page
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
App.Current.IsIdleChanged += onIsIdleChanged;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
App.Current.IsIdleChanged -= onIsIdleChanged;
}
private void onIsIdleChanged(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine($"IsIdle: {App.Current.IsIdle}");
}
}
Run Code Online (Sandbox Code Playgroud)
当指针在应用程序窗口内没有移动10秒时检测到空闲.这也适用于仅限触摸的应用程序(如移动应用程序),因为PointerMoved也会在点击窗口时触发.
| 归档时间: |
|
| 查看次数: |
1551 次 |
| 最近记录: |