I want to write a function that returns true if mouse doesn't move for given amount of time.
I've tried Mouse.GetPosition() but it keeps returning the same coordinates.
private bool MouseNotMoves(int time)
{
Point currentMouseCoord = Mouse.GetPosition(this);
TimeSpan timeSpan = new TimeSpan(0,0,0,0,0);
DateTime start = DateTime.Now;
while (timeSpan.TotalMilliseconds <= time)
{
System.Threading.Thread.Sleep(100);
timeSpan = DateTime.Now - start;
Point newMouseCoord = Mouse.GetPosition(this);
if (currentMouseCoord != newMouseCoord)
start = DateTime.Now;
currentMouseCoord = newMouseCoord;
}
return true;
}
I want to get mouse coordinates when calling the function and then again after some time and compare them, the problem is that the function always returns true after exact given time. When i try debugging the mouse coordinates never change even if I move the mouse.
I'm quite new to programing so if there's a better way to achieve this I'd really appreciate any suggestions.
This is an example of what I meant in the comments by inverting the logic. It's quite dirty, but I believe it highlights the idea.
private bool _mouseMoved;
private async void Button_Click(object sender, RoutedEventArgs e)
{
MyTextBlock.Text = (await IfMouseMoved(TimeSpan.FromSeconds(4))).ToString();
}
private async Task<bool> IfMouseMoved(TimeSpan timeSpan)
{
MouseMove += MainWindow_MouseMove;
try
{
_mouseMoved = false;
await Task.Delay(timeSpan);
return _mouseMoved;
}
finally
{
MouseMove -= MainWindow_MouseMove;
}
}
private void MainWindow_MouseMove(object sender, MouseEventArgs e)
{
_mouseMoved = true;
}
UPD. The same solution can be written concisely using local function for the callback:
private async Task<bool> IfMouseMoved(TimeSpan timeSpan)
{
var mouseMoved = false;
void MouseMovedCallback(object sender, MouseEventArgs e)
{
mouseMoved = true;
}
MouseMove += MouseMovedCallback;
try
{
await Task.Delay(timeSpan);
return mouseMoved;
}
finally
{
MouseMove -= MouseMovedCallback;
}
}
The following code will work only when the cursor is in your application.
XAML
<Grid MouseMove="Grid_MouseMove">
</Grid>
Code Behind
System.Timers.Timer timer;
public YourConstructor()
{
InitializeComponent();
// Create a timer with a ten second interval.
timer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
timer.Elapsed += OnTimedEvent;
// Raise the Elapsed event only once.
timer.AutoReset = false;
// Start the timer.
timer.Start();
}
private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e)
{
// Mouse has not moved for 10s.
}
private void Grid_MouseMove(object sender, MouseEventArgs e)
{
// Reset the timer.
if(timer.Enabled)
{
timer.Stop();
}
timer.Start();
}
More info about System.Timers.Timer
Related
Is there any way to detect if ListView or CollectionView is scrolling by user and not from ScrollTo method?
I am using ScrollTo as the example below:
colViewCategories.ScrollTo(categoryItem, null, ScrollToPosition.Center, true);
Or if i can disable Scrolled Event till ScrollTo Method will stop to scroll.
I finally found my answer.
bool scrollAnimationIsRaised=false;
int previousindex = 0;
private System.Timers.Timer tmr = new System.Timers.Timer();
private void InitTimer
{
tmr.Interval = 500; //waiting 500ms after scrollTo has Stop for not having conflicts
tmr.Elapsed += Tmr_Elapsed;
}
private void ButtonClick(object sender, EventArgs e)
{
scrollAnimationIsRaised = true;
listview.ScrollTo(50);
}
private void ListviewItems_Scrolled(object sender, ItemsViewScrolledEventArgs e)
{
if(scrollAnimationIsRaised)
{
//ScrollToEvent Is Fired
if (e.LastVisibleItemIndex == previousindex)
tmr.Start();
previousindex = e.LastVisibleItemIndex;
}
else
{
//ScrollTo event has finished
}
}
private void Tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
tmr.Stop();
scrollAnimationIsRaised = false;
}
Here's the pseudo code:
private void ForgetSave()
{
if (the SaveRegularly method hasn't been used within 3 mins)
MessageBox.Show("Would you like to save any changes before closing?")
......... the code continues.
}
else
{
this.close();
}
Does anybody know how to write the first line of the if statement?
Simply remember when the last save time was:
private const TimeSpan saveTimeBeforeWarning = new TimeSpan(0,1,0); //1 minute
private static DateTime _lastSave = DateTime.Now;
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if ((DateTime.Now - _lastSave) > saveTimeBeforeWarning)
{
if(MessageBox.Show("Would you like to save any changes before closing?") == DialogResult.Yes);
{
Save();
}
}
}
private void Save()
{
//save data
_lastSave = DateTime.Now
}
As Ahmed suggested you can use a timer and a flag to know when you have to display the message, I left you a piece of code to get you started
private const int SAVE_TIME_INTERVAL = 3 * 60 * 1000;
private bool iWasSavedInTheLastInterval = true;
private System.Windows.Forms.Timer timer;
public Form1()
{
InitializeComponent();
//Initialize the timer to your desired waiting interval
timer = new System.Windows.Forms.Timer();
timer.Interval = SAVE_TIME_INTERVAL;
timer.Tick += Timer_Tick;
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
//If the timer counts that amount of time we haven't saved in that period of time
iWasSavedInTheLastInterval = false;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (iWasSavedInTheLastInterval == false)
{
MessageBox.Show("Would you like to save any changes before closing?");
}
}
private void btnSave_Click(object sender, EventArgs e)
{
//If a manual save comes in then we restart the timer and set the flag to true
iWasSavedInTheLastInterval = true;
timer.Stop();
timer.Start();
}
Got a problem at the moment, I'm using a timer to do animations and I want to be able to decide where to start using Start and Stop integers as i'll show below.
private void Button1_Click(object sender, EventArgs e)
{
AnimateKey(0,100);
}
private void AnimateKey(int Start, int Stop)
{
myTimer.Interval = 5;
myTimer.Tick += new EventHandler(myTimer_Tick);
myTimer.Enabled = true;
myTimer.Start();
}
private void myTimer_Tick(object sender, EventArgs e)
{
lock (myTimer)
{
int StartingFrame = Start;
int StopFrame = Stop;
etc...etc..
}
}
Now my problem is that I want to pass the values 0 and 100 to the Timer Tick event but I have no idea on how to go about doing it.
How can I get the Integers 0 and 100 from the button click to the timer tick ?
Just use a lambda when defining the tick event handler to close over the parameters you need:
private void AnimateKey(int Start, int Stop)
{
myTimer.Interval = 5;
myTimer.Tick += (s, args) => myTimer_Tick(Start, Stop);
myTimer.Enabled = true;
myTimer.Start();
}
private void myTimer_Tick(int Start, int Stop)
{
//Do stuff
}
Also note that the Tick event of the Timer that you're using will be fired in the UI thread, so there is no need for a lock; the code is already synchronized.
use a class with all info:
public class TimerInfo
{
public int Start;
public int Stop;
}
store an instance in timer's Tag
myTimer.Tag = new TimerInfo { Start = 0, Stop = 100 };
inside the eventhandler you access this info
myTimer = (Timer)sender;
TimerInfo ti = (TimerInfo)myTimer.Tag;
Somewhat hard to understand what you mean, but let's give it a try.
If you ment you want to pass the integers start and stop to the function TimerTick, you probably dont understand the EventArgs parameter. EventArgs is ment to store the arguements which are relevant to your scenario - and the solution is simple.
class myTimerEventArgs:EventArgs // Declaring your own event arguements which you want to send
{
public int start{get;set;}
public int stop {get;set;}
/*Constructor, etc...*/
}
...
//Making the call inside another class:
myTimer_Tick(this,new myTimerEventArgs(0,100);
However, I could be misunderstanding you; If are talking about counting the ticks until it reaches 100 ticks (/intervals), the solution is a simple function added to the event, which would probably look like this:
int Count = 0;
...
private void Counter(object sender, EventArgs e)
{
Count++;
}
...
private void AnimateKey(int Start, int Stop)
{
myTimer.Interval = 5;
myTimer.Tick += new EventHandler(myTimer_Tick);
myTimer.Tick += new EventHandler(Counter);
myTimer.Enabled = true;
myTimer.Start();
while(Count!=100);
myTimer.Stop();
}
Hope I helped, have a nice day :)
I have a background worker which i am using to perform some task. Its working as expected. However, i have a timer that i want to add and make it start the bw and counting like 10 seconds after page load. I put my timer.Interval to 10000. the timer has a tick events as below
private DateTime dateETA;
private void TimerEventHandler(object sender, EventArgs e)
{
while (bw.CancellationPending ==false)
{
if (timerPro.Enabled == true)
{
dateETA = Convert.ToDateTime("1/1/0001 00:00:00");
dateETA = dateETA.AddMilliseconds(timerPro.Interval);
lblETA.Visible = true;
lblETA.Text = "Elapsed Time : " + Convert.ToString(dateETA.TimeOfDay);
// SetText("timer");
}
}
}
My background worker async is on the page contructor method and therefore run on load. just like below
if (bw.IsBusy != true)
{
this.btnPause.Enabled = true;
this.btnStop.Enabled = true;
btnStart.Enabled = false;
// timerPro.Start();
bw.RunWorkerAsync();
}
I wanted to start the timer together with my task therefore i put it before my bw.async . Then i realized the timer tick events does not fire when put before or within the dowork method of the background worker. I thought may be the bw thread is blocking the event from firing then i use an invoke method like below within the dowork in my attempt to start the timer or trigger the tick event of the timer.
this.Invoke((MethodInvoker)(() => { timerPro.Enabled = true; }));
It still does not fire. I am confused and any help or alternative would be appreciated.
I think you just want a running elapsed timer while the backgroundworker does its thing?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
private void Form1_Load(object sender, EventArgs e)
{
timerPro.Interval = 1000;
timerPro.Tick +=new EventHandler(TimerEventHandler);
SW.Start();
timerPro.Start();
bw.RunWorkerAsync();
}
private void TimerEventHandler(object sender, EventArgs e)
{
lblETA.Visible = true;
TimeSpan TS = SW.Elapsed;
string elapsed = String.Format("{0}:{1}:{2}", TS.Hours.ToString("00"), TS.Minutes.ToString("00"), TS.Seconds.ToString("00"));
lblETA.Text = "Elapsed Time : " + elapsed;
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
// ... do some work ...
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
timerPro.Stop();
}
}
Could any one help me to stop my timer in windows form C3 application? I added timer in form using designer and interval is set as 1000; I would like to do some actions after 5 seconds of waiting after button click. Please check the code and advise me. Problem now is I get MessageBox2 infinitely and never gets the timer stop.
static int count;
public Form1()
{
InitializeComponent();
timer1.Tick += timer1_Tick;
}
public void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
while(count>5)
{
....dosome actions...
}
}
private void timer1_Tick(object sender, EventArgs e)
{
count1++;
MessageBox.Show("Messagebox2");
if (count1 == 5)
{
//timer1.Enabled = false; timer1.Stop();
((System.Timers.Timer)sender).Enabled = false;
MessageBox.Show("stopping timer");
}
}
I would render the count useless and just use the timer 1 interval property and put your actions in the timer1_Tick event.
public void button1_Click(object sender, EventArgs e)
{
timer1.Interval = 5000;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
MessageBox.Show("stopping timer");
// Your other actions here
}
You are incrementing count1 and checking count.
while(count1 > 5)
{
...dosome actions...
}
Which Timer do you use? Because C# supports class Timer from two different namespaces. One is from Forms, the other is from System.Timers. I would suggest you to use the other one - System.Timers.Timer.
Timer t = new Timer(20000); // created with 20seconds
t.Enabled = true; // enables firing Elapsed event
t.Elapsed += (s, e) => {
\\do stuff
};
t.Start();
In this short code you can see how the timer is created and enabled. By registering to the Elapsed event you explicitly say what to do after the time elapses. and this is done just once. Of course, there are some changes needed in case user clicks button before your limit is reached. But this is highly dependent on behavior of the action you demand.