How to wait until a timer stops - c#

I need to wait the next line to be waiting until a timer finishes.
public void animation(){
timer1.start();
labelStatus.Visibility=true;
}
I want the labelStatus to be visible after the timer1 finished.
private void timer1_Tick(object sender, EventArgs e)
{
int fromX = lblMove.Location.X;
int fromY = lblMove.Location.Y;
if (fromY > moveToY)
{
Y = Y - 5;
lblMove.Location = new Point(fromX, Y);
}
else if (fromY < moveToY)
{
Y = Y + 5;
lblMove.Location = new Point(fromX, Y);
}
else
{
timer1.Stop();
}
}
thanks in advance.

Simplest solution I can think of is this
public void animation(){
timer1.start();
labelStatus.Visibility=false;
}
private void timer1_Tick(object sender, EventArgs e)
{
[...]
else if (fromY < moveToY)
{
Y = Y + 5;
lblMove.Location = new Point(fromX, Y);
}
else
{
timer1.Stop();
labelStatus.Visibility = true;
}
}
This way when you stop the timer you make the label visible. There are many other ways of doing this but this should be simple.

Second method.
Apparently Timer doesn't have a "OnStopped" event to hook to (unless you want to try with dispose). However a Timer has a System.Timer.Timer.Enabled flag for telling you that it's running.
It's not a clean solution, but you could create a new Thread and Poll "timer.Enabled" until it turns false.

Related

visual studio timer ticks displayed?

This is my code for my drag race but I am wondering, I have my timer but how do I place it on a label?
private void tmrRaceTimerNamo_Tick(object sender, EventArgs e)
{
//car speed
pcbCar1Namo.Left = pcbCar1Namo.Left + 10;
pcbCar2Namo.Left = pcbCar2Namo.Left + 4;
pcbCar3Namo.Left = pcbCar3Namo.Left + 5;
pcbCar4Namo.Left = pcbCar4Namo.Left + 7;
//car stops at finish
AllCarsOnFinishNamo();
}
private void AllCarsOnFinishNamo()
{
if (pcbCar1Namo.Left > pcbFininshNamo.Right)
{
pcbCar1Namo.Left = pcbFininshNamo.Right;
}
if (pcbCar2Namo.Left > pcbFininshNamo.Right)
{
pcbCar2Namo.Left = pcbFininshNamo.Right;
tmrRaceTimerNamo.Enabled = false;
}
if (pcbCar3Namo.Left > pcbFininshNamo.Right)
{
pcbCar3Namo.Left = pcbFininshNamo.Right;
}
if (pcbCar4Namo.Left > pcbFininshNamo.Right)
{
pcbCar4Namo.Left = pcbFininshNamo.Right;
}
}
private void btnGoNamo_Click(object sender, EventArgs e)
{
//start of timer
tmrRaceTimerNamo.Enabled = true;
}
You can simply set the label to the value on each tick or update. For example in your tmrRaceTimerNamo_Tick(object sender, EventArgs e) method, you can set the labels text property to the time.
I dont exactly know what you want to show but i think you want to see the fps you are getting while playing your drag race game so here is a function for afps counter
private static int lastTick;
private static int lastFrameRate;
private static int frameRate;
public static int CalculateFrameRate()
{
label.Text = CalculateFrameRate().ToString();
if (System.Environment.TickCount - lastTick >= 1000)
{
lastFrameRate = frameRate;
frameRate = 0;
lastTick = System.Environment.TickCount;
}
frameRate++;
return lastFrameRate;
}

How to change the window position in wpf on a mouse click

I need to change the position of a window on mouse click.
here is the code.
private void Button_Click(object sender, RoutedEventArgs e)
{
for(int i=0; i<50; i++)
{
this.Top -= i;
this.Left -= i;
}
}
But whenever i run this program only the last position is shown. My intention is to move it continuosly till the end of loop.
Finally i found the answer myself. It s working perfectly as i expected. I used SynchronizationContext which can post Actions to update controls on UI thread.
public partial class Splash : Window
{
SynchronizationContext sc;
System.Timers.Timer t;
double i=0;
double tempTop;
double angle = 0;
public Splash()
{
InitializeComponent();
sc=SynchronizationContext.Current;
}
private void Move(object sender, MouseEventArgs e)
{
DragMove();
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void btnMinim_Click(object sender, RoutedEventArgs e)
{
this.WindowState = WindowState.Minimized;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
l1.Content = "Helicopter Moving";
if(t!=null)
{
t.Stop();
t.Dispose();
}
//for (double i = 0; i < 1; i += 0.05)
//{
// this.Top -= i;
// this.Left -= i;
// Thread.Sleep(100);
//}
//l1.Content = "Helicopter Stopped";
tempTop = this.Top;
t = new System.Timers.Timer();
t.Interval = 10;
t.Enabled = true;
t.Elapsed += Change;
t.Start();
}
void Change(object sender, EventArgs e)
{
if (i <= 3)
{
sc.Post(o =>
{
this.Top = tempTop * (Math.Cos(Math.PI * angle / 180));
this.Left -= i;
angle = (angle >= 360) ? 0 : ++angle;
i = i + 0.01;
}, null);
}
else
{
t.Stop();
i = i * -1;
}
}
}
}
Try this should work Thread.Sleep will not work for you as its a UI thread. You need timer to make this work
Timer t;
private void Button_Click(object sender, RoutedEventArgs e)
{
i=0;
if(t!=null)
{
t.Stop();
t.Dispose();
}
t = new Timer();
t.Interval = 800;
t.Enabled = true;
t.Tick += T_Tick;
t.Start();
}
int i=0;
private static void T_Tick(object sender, EventArgs e)
{
if(i<=50)
{
this.Top -= i;
this.Left -= i;
i++;
}
else
t.Stop();
}
Just start an animation when your click event triggers. You can define how long should the animation last.
Basic benefit of using animations instead of doing calculations manually is animations being run in separated thread, so you don't loose application's responsiveness.
What is more, you can edit your animations in separated tools, such as Blend without the need to verifying animations in runtime.
Few sources:
http://www.wpf-tutorial.com/styles/trigger-animations-enteractions-exitactions/
http://dotnetslackers.com/articles/wpf/IntroductionToWPFAnimations.aspx
http://www.wpftutorial.net/Animation.html

replacement for thread.sleep

I'm trying to make a Tamagochi but I've ran into a problem. I have a Progressbar with a max value of 300. Every 5-8 seconds the Progressbar empties a bit. Once it gets below 250 you're allowed to sleep.
Here is the code i have so far:
private void BtnSleep_Click(object sender, EventArgs e)
{
if (PgbSleep.Value <= 250)
{
int temp = PgbSleep.Maximum - PgbSleep.Value;
if (temp + PgbSleep.Value >= 300)
{
Timer2.Stop();
Thread.Sleep(20000);
PgbSleep.Value = 300;
Timer2.Start();
}
}
else
{
MessageBox.Show("Your pokemon is not tired enough to sleep! try playing with it");
}
}
I'm trying to find a replacement for the
Thread.Sleep(20000);
But dont know what to use. Any help would be much appreciated!
The
Thread.Sleep(20000);
Is supposed to be a cooldown, once its completed the user is allowed to sleep again if the requirements are met.
Try using a timer:
Timer sleepTimer = new Timer(20000); //Creates a timer for sleeping
public MyClass()
{
sleepTimer.Elapsed += new EventHandler((s, e) => WakeUp());
}
private void BtnSleep_Click(object sender, EventArgs e)
{
if (PgbSleep.Value <= 250)
{
int temp = PgbSleep.Maximum - PgbSleep.Value;
if (temp + PgbSleep.Value >= 300)
{
Timer2.Stop();
sleepTimer.Start();
}
}
else
{
MessageBox.Show("Your pokemon is not tired enough to sleep! try playing with it");
}
}
private void WakeUp()
{
PgbSleep.Value = 300;
Timer2.Start();
}

C#, Constantly monitor battery level

I am designing a program that depends on monitoring the battery level of the computer.
This is the C# code I am using:
PowerStatus pw = SystemInformation.PowerStatus;
if (pw.BatteryLifeRemaining >= 75)
{
//Do stuff here
}
My failed attempt of the while statement, it uses all the CPU which is undesirable.
int i = 1;
while (i == 1)
{
if (pw.BatteryLifeRemaining >= 75)
{
//Do stuff here
}
}
How do I monitor this constantly with an infinite loop so that when it reaches 75% it will execute some code.
Try Timer:
public class Monitoring
{
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
public Monitoring()
{
timer1.Interval = 1000; //Period of Tick
timer1.Tick += timer1_Tick;
}
private void timer1_Tick(object sender, EventArgs e)
{
CheckBatteryStatus();
}
private void CheckBatteryStatus()
{
PowerStatus pw = SystemInformation.PowerStatus;
if (pw.BatteryLifeRemaining >= 75)
{
//Do stuff here
}
}
}
UPDATE:
There is another way to do your task complete. You can use SystemEvents.PowerModeChanged.
Call it and wait for changes, monitor the changes occured then do your stuff.
static void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
{
if (e.Mode == Microsoft.Win32.PowerModes.StatusChange)
{
if (pw.BatteryLifeRemaining >= 75)
{
//Do stuff here
}
}
}
While loop will cause your UI to response poor and the application will get crashed. You can solve this by using many ways. Please check out the below code snippet will help your needs.
public delegate void DoAsync();
private void button1_Click(object sender, EventArgs e)
{
DoAsync async = new DoAsync(GetBatteryDetails);
async.BeginInvoke(null, null);
}
public void GetBatteryDetails()
{
int i = 0;
PowerStatus ps = SystemInformation.PowerStatus;
while (true)
{
if (this.InvokeRequired)
this.Invoke(new Action(() => this.Text = ps.BatteryLifePercent.ToString() + i.ToString()));
else
this.Text = ps.BatteryLifePercent.ToString() + i.ToString();
i++;
}
}
BatteryChargeStatus.Text = SystemInformation.PowerStatus.BatteryChargeStatus.ToString();
BatteryFullLifetime.Text = SystemInformation.PowerStatus.BatteryFullLifetime.ToString();
BatteryLifePercent.Text = SystemInformation.PowerStatus.BatteryLifePercent.ToString();
BatteryLifeRemaining.Text = SystemInformation.PowerStatus.BatteryLifeRemaining.ToString();
PowerLineStatus.Text = SystemInformation.PowerStatus.PowerLineStatus.ToString();
If you want to perform some operation just convert these string values into the integer.

Can't seem to get progressbar to animate

OK so I've have a problem looking like this.
public Class A{
public A(){
progressBar.Style = ProgressBarStyle.Marquee;
progressBar.MarqueeAnimationSpeed = 0;
}
public void DoSomething(){
if(checkpasses){
progressBar.MarqueeAnimationSpeed = 100;
//Do something here...
progressBar.MarqueeAnimationSpeed = 0;
}
else
//Do nothing...
}
}
The problem is that my progressbar wont start moving at all. First I figured that it wont create a new thread by itself (which I find wired) so I tried creating a thread but still the same result. Nothing happens. Is it something I've forgotten?
Call
Application.EnableVisualStyles();
at the very beginning of your application.
Your "do something here" code is going to block the UI thread so you will not see the progress bar update until after the DoSomething method completes. At that time you are setting the animation speed back to 0.
Try putting your "do something here" code on a separate thread. When that thread completes set the animation speed back to 0.
Something like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.MarqueeAnimationSpeed = 0;
progressBar1.Style = ProgressBarStyle.Blocks;
progressBar1.Value = progressBar1.Minimum;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
DoSomething();
}
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Style = ProgressBarStyle.Marquee;
progressBar1.MarqueeAnimationSpeed = 100;
backgroundWorker1.RunWorkerAsync();
}
private void DoSomething()
{
Thread.Sleep(2000);
}
}
I am not sure if this is the best solution, but I have it this way:
//this is the action item (button click)
private void importSFNFReportButton_Click(object sender, EventArgs e)
{ //I run
backgroundWorker6Progress.RunWorkerAsync(); //this is how I start the progress bar 'movement'
bgwImportSF.RunWorkerAsync(); //this is another task that is lauchned after the progress bar is initiated
}
This is actual background worker
private void backgroundWorker6Progress_DoWork(object sender, DoWorkEventArgs e)
{
bool cont = true;
while (cont)
{
PauseForMilliSeconds(100);
updateProgressbar1(false);
if (noTasksExistCheck())
{
updateProgressbar1(true);
cont = false;
}
}
}
this is a delegate- I call it to auto-increase the progress bar indicator
delegate void updateProgressBarStatus(bool done);
private void updateProgressbar1(bool done)
{
if (progressBar1.InvokeRequired)
{
updateProgressBarStatus del = new updateProgressBarStatus(updateProgressbar1);
progressBar1.Invoke(del, new object[] { done });
}
else
{
if (progressBar1.Value == progressBar1.Maximum)
{
progressBar1.Value = progressBar1.Minimum;
}
progressBar1.PerformStep();
if (done == true)
{
progressBar1.Value = progressBar1.Minimum;
}
}
}
I control it via the function that has to check a global varibale
noTasksExistCheck()
This is the timer pause
public static DateTime PauseForMilliSeconds(int MilliSecondsToPauseFor)
{
System.DateTime ThisMoment = System.DateTime.Now;
System.TimeSpan duration = new System.TimeSpan(0, 0, 0, 0, MilliSecondsToPauseFor);
System.DateTime AfterWards = ThisMoment.Add(duration);
while (AfterWards >= ThisMoment)
{
System.Windows.Forms.Application.DoEvents();
ThisMoment = System.DateTime.Now;
}
return System.DateTime.Now;
}
Just to complement a bit more, the solution suggested by Dave will only work if Konstantin's suggested code exists. Otherwise, one should think of manually increasing the progressbar.value in a loop by the following code within the DoWork:
BeginInvoke(new MethodInvoker( () => progressBarSave.Value += progressBarSave.Step));

Categories