12

I was looking for the best approach to find out the if my users are idle in my WPF application. Currently, I take this idle time from operating system, and if they minimize the application, and go and search in Internet, there is a process in the operating system, so Operation system does not consider this as inactivity time even though they are not doing anything inside the application. However, I would like to find out if they have not clicked or do anything inside my application.

This is how I can that idle time right now.

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
         }
    }
paradisonoir
  • 2,892
  • 9
  • 30
  • 41
  • See [this StackOverflow answer](http://stackoverflow.com/questions/744980/hide-mouse-cursor-after-an-idle-time/745227#745227) to another question regarding idle time for a nice solution. – cdiggins Jan 09 '10 at 19:37

4 Answers4

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

void ComponentDispatcher_ThreadIdle(object sender, EventArgs e)
    {
        //do your idle stuff here
    }
Andreas
  • 3,843
  • 3
  • 40
  • 53
3

See this answer: Application.Idle event not firing in WPF application

ComponentDispatcher.ThreadIdle is the event you are looking for.

Community
  • 1
  • 1
xt1
  • 408
  • 3
  • 11
  • +1, but might not be what the question wants. A user being idle usually means not using mouse or keyboard. The dispatcher also dispatches things like a timer so might be less idle than you might think. – Lars Truijens Jun 14 '11 at 20:29
1
  1. For such scenarios, we need a Timer which fires back some event after a timeinterval.

  2. And most importantly, we need a callback / eventhandler which gets called everytime any activity of any kind happens in our application, so that we know that our application is running.

Point 1 can be handled using DispatcherTimer.

Point 2 can be handled using public event CanExecuteRoutedEventHandler CanExecute; .

Putting it altogether :

MainWindow.xaml

xmlns:cmd="clr-namespace:System.Windows.Input; assembly=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;
        }
    }

We can easily extend this approach to fit our needs.

AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38
0

How about subscribing to SENS events?

Here's another link.

Sergey Aldoukhov
  • 22,316
  • 18
  • 72
  • 99