gpt4 book ai didi

wpf - 如何确定 MVVM 应用程序中的非事件状态?

转载 作者:行者123 更新时间:2023-12-04 18:51:58 27 4
gpt4 key购买 nike

我有一个 MVVM 信息亭应用程序,当它处于非事件状态一段时间后,我需要重新启动它。我正在使用 Prism 和 Unity 来促进 MVVM 模式。我已经重新启动了,我什至知道如何处理计时器。我想知道的是如何知道事件(即任何鼠标事件)何时发生。我知道如何做到这一点的唯一方法是订阅主窗口的预览鼠标事件。这打破了 MVVM 的想法,不是吗?

我曾考虑将我的窗口公开为将这些事件公开给我的应用程序的接口(interface),但这将要求窗口实现该接口(interface),这似乎也破坏了 MVVM。

最佳答案

另一种选择是使用 Windows API 方法 GetLastInputInfo .

一些注意事项

  • 我假设是 Windows,因为它是 WPF
  • 检查您的信息亭是否支持 GetLastInputInfo
  • 我对MVVM一无所知。此方法使用与 UI 无关的技术,因此我认为它对您有用。

  • 用法很简单。调用 UserIdleMonitor.RegisterForNotification。您传入一个通知方法和一个 TimeSpan。如果用户事件发生然后在指定的时间段内停止,则调用通知方法。您必须重新注册才能获得另一个通知,并且可以随时取消注册。如果 49.7 天(加上 idlePeriod)没有事件,将调用通知方法。
    public static class UserIdleMonitor
    {
    static UserIdleMonitor()
    {
    registrations = new List<Registration>();
    timer = new DispatcherTimer(TimeSpan.FromSeconds(1.0), DispatcherPriority.Normal, TimerCallback, Dispatcher.CurrentDispatcher);
    }

    public static TimeSpan IdleCheckInterval
    {
    get { return timer.Interval; }
    set
    {
    if (Dispatcher.CurrentDispatcher != timer.Dispatcher)
    throw new InvalidOperationException("UserIdleMonitor can only be used from one thread.");
    timer.Interval = value;
    }
    }

    public sealed class Registration
    {
    public Action NotifyMethod { get; private set; }
    public TimeSpan IdlePeriod { get; private set; }
    internal uint RegisteredTime { get; private set; }

    internal Registration(Action notifyMethod, TimeSpan idlePeriod)
    {
    NotifyMethod = notifyMethod;
    IdlePeriod = idlePeriod;
    RegisteredTime = (uint)Environment.TickCount;
    }
    }

    public static Registration RegisterForNotification(Action notifyMethod, TimeSpan idlePeriod)
    {
    if (notifyMethod == null)
    throw new ArgumentNullException("notifyMethod");
    if (Dispatcher.CurrentDispatcher != timer.Dispatcher)
    throw new InvalidOperationException("UserIdleMonitor can only be used from one thread.");

    Registration registration = new Registration(notifyMethod, idlePeriod);

    registrations.Add(registration);
    if (registrations.Count == 1)
    timer.Start();

    return registration;
    }

    public static void Unregister(Registration registration)
    {
    if (registration == null)
    throw new ArgumentNullException("registration");
    if (Dispatcher.CurrentDispatcher != timer.Dispatcher)
    throw new InvalidOperationException("UserIdleMonitor can only be used from one thread.");

    int index = registrations.IndexOf(registration);
    if (index >= 0)
    {
    registrations.RemoveAt(index);
    if (registrations.Count == 0)
    timer.Stop();
    }
    }

    private static void TimerCallback(object sender, EventArgs e)
    {
    LASTINPUTINFO lii = new LASTINPUTINFO();
    lii.cbSize = Marshal.SizeOf(typeof(LASTINPUTINFO));
    if (GetLastInputInfo(out lii))
    {
    TimeSpan idleFor = TimeSpan.FromMilliseconds((long)unchecked((uint)Environment.TickCount - lii.dwTime));
    //Trace.WriteLine(String.Format("Idle for {0}", idleFor));

    for (int n = 0; n < registrations.Count; )
    {
    Registration registration = registrations[n];

    TimeSpan registeredFor = TimeSpan.FromMilliseconds((long)unchecked((uint)Environment.TickCount - registration.RegisteredTime));
    if (registeredFor >= idleFor && idleFor >= registration.IdlePeriod)
    {
    registrations.RemoveAt(n);
    registration.NotifyMethod();
    }
    else n++;
    }

    if (registrations.Count == 0)
    timer.Stop();
    }
    }

    private static List<Registration> registrations;
    private static DispatcherTimer timer;

    private struct LASTINPUTINFO
    {
    public int cbSize;
    public uint dwTime;
    }

    [DllImport("User32.dll")]
    private extern static bool GetLastInputInfo(out LASTINPUTINFO plii);
    }

    更新

    修复了如果您尝试从通知方法重新注册可能会死锁的问题。

    修复了未签名的数学并添加了未选中的。

    计时器处理程序中的轻微优化,仅根据需要分配通知。

    注释掉调试输出。

    更改为使用 DispatchTimer。

    增加了取消注册的能力。

    在公共(public)方法中添加了线程检查,因为这不再是线程安全的。

    关于wpf - 如何确定 MVVM 应用程序中的非事件状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4865376/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com