在WPF应用程序中获取不活动/空闲时间

12

我正在寻找最佳方法来判断我的WPF应用程序中的用户是否处于空闲状态。目前,我从操作系统获取这个空闲时间,如果他们最小化应用程序并在互联网上搜索,那么操作系统中会有一个进程,因此操作系统不会认为这是空闲时间,即使他们在应用程序内部没有做任何事情。然而,我想找出他们是否没有在我的应用程序内点击或执行任何操作。

这就是我现在可以获得空闲时间的方式。

myApplication.MainMethod()
    {
        System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
        myTimer .Interval = 1000;
        myTimer .Tick += new EventHandler(Timer_Tick);
        myTimer .Start();
    }

    void Timer_Tick(object sender, EventArgs e)
    {
        int idleTime= (int)Win32.GetIdleTime();
        if (idleTime<certainNumber)
        {
         //do this
         }
    }

请参考这个StackOverflow答案,了解有关空闲时间的一个好的解决方案。 - cdiggins
4个回答

19
public MainWindow()
    {
        InitializeComponent();
        ComponentDispatcher.ThreadIdle += new System.EventHandler(ComponentDispatcher_ThreadIdle);
    }

void ComponentDispatcher_ThreadIdle(object sender, EventArgs e)
    {
        //do your idle stuff here
    }

3

+1,但可能不是问题想要的。用户处于闲置状态通常意味着不使用鼠标或键盘。调度程序还会分派诸如计时器之类的东西,因此它可能会比您想象的更少闲置。 - Lars Truijens

1
  1. 对于这种场景,我们需要一个Timer,它在时间间隔后触发某个事件

  2. 最重要的是,我们需要一个回调函数/事件处理程序,每当应用程序中发生任何活动时,都会被调用,以便我们知道我们的应用程序正在运行

点1可以使用DispatcherTimer来处理。

点2可以使用public event CanExecuteRoutedEventHandler CanExecute;来处理。

将其整合起来:

MainWindow.xaml

xmlns:cmd="clr-namespace:System.Windows.Input; assembly=Presentationcore"

意思是:定义命名空间cmd,它属于System.Windows.Input,并且这个命名空间的程序集是Presentationcore。
    <!-- a do nothing button -->
    <Button  Command="{x:Static cmd:NavigationCommands.BrowseBack}" Visibility="Collapsed">
        <Button.CommandBindings>
    <!-- we can use any pre-defined / user-defined command -->
            <CommandBinding Command="{x:Static cmd:NavigationCommands.BrowseBack}" CanExecute="CommandBinding_CanExecute_1"/>
        </Button.CommandBindings>
    </Button>

MainWindow.xaml.cs

    public partial class MainWindow: Window
    {
        DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.ApplicationIdle);
        bool running = true;

        public MainWindow()
        {
            InitializeComponent();
            timer.Interval = TimeSpan.FromSeconds(5);
            timer.Tick += timer_Tick;
            timer.Start();
        }

        private void CommandBinding_CanExecute_1(object sender, CanExecuteRoutedEventArgs e)
        {
            running = true;
            e.CanExecute = true;
        }

        void timer_Tick(object sender, EventArgs e)
        {
            if (!running)
                App.Current.Shutdown();

            running = false;
        }
    }

我们可以轻松地将这种方法扩展到适应我们的需求。

0

我希望在不调用/查询外部服务的情况下内部控制一切。 - paradisonoir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接