CountDown is Not Working Correctly in Xamarin - c#

In my Xamarin App, I'm facing a problem with a count down.
I want to restart the count down from 4 seconds, every time when the timer starts.
For TimeSpan.FromSeconds(0), what I get is 0, 3, 2, 1, for the TimeSpan.FromSeconds(0) part of code, it prints the count down quickly and in TimeSpan.FromSeconds(8) it goes into -1, -2 too.
Code
private Timer _timer;
private int _countSeconds;
public CameraViewModel() {
Device.StartTimer(TimeSpan.FromSeconds(0), () =>
{
_timer = new Timer();
_timer.Interval = 1000;
_timer.Elapsed += OnTimedEvent;
_countSeconds = 4;
_timer.Enabled = true;
return false;
});
Device.StartTimer(TimeSpan.FromSeconds(4), () =>
{
_timer = new Timer();
_timer.Interval = 1000;
_timer.Elapsed += OnTimedEvent;
_countSeconds = 4;
_timer.Enabled = true;
return false;
});
Device.StartTimer(TimeSpan.FromSeconds(8), () =>
{
// above code used here again
return false;
});
}
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
_countSeconds--;
CountDown = _countSeconds;
if (_countSeconds == 0)
{
_timer.Stop();
}
}
#region Bindable Properties
private string _countDown;
public string CountDown
{
get => _countDown;
set => this.RaiseAndSetIfChanged(ref _countDown, value);
}
#endregion

to countdown from 4..1 and reset
create a class level variable or property for your COunter
int Counter = 4;
create a single timer - there is no need for multiple timers
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
timer.AutoReset = true;
timer.Start();
when your timer fires
void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Console.WriteLine(Counter);
Counter--;
if (Counter < 0) Counter = 4;
}

Related

Display time elapsed

I need to display the elapsed time dynamically. My code will pop up a message based on an interval value.
public void button1_Click(object sender, EventArgs e)
{
this.TopMost = true;
DialogResult result1 = MessageBox.Show("Add some notes to your current ticket?",
"Add Notes",
MessageBoxButtons.YesNo);
if (result1 == DialogResult.Yes)
{
Timer tm;
tm = new Timer();
int minutes = int.Parse(textBox2.Text);
tm.Interval = (int)TimeSpan.FromMinutes(minutes).TotalMilliseconds;
tm.Tick += new EventHandler(button1_Click);
tm.Enabled = true;
string pastebuffer = DateTime.Now.ToString();
pastebuffer = "### Edited on " + pastebuffer + " by " + txtUsername.Text + " ###";
Clipboard.SetText(pastebuffer);
tm.Start();
}
else if (result1 == DialogResult.No)
{
}
this.TopMost = false;
}
If I have defined 15 mins in my interval how do i get the countdown to show in a label?
You should store end-time in a filed at form level and then in Tick event handler of the timer check the difference between the end-time and now and update a label which you want to show count-down timer:
private DateTime endTime;
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
private void button1_Click(object sender, EventArgs e)
{
var minutes = 0;
if (int.TryParse(textBox1.Text, out minutes) && timer.Enabled == false)
{
endTime = DateTime.Now.AddMinutes(minutes);
timer.Interval = 1000;
timer.Tick -= new EventHandler(timer_Tick);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
UpdateText();
}
}
void timer_Tick(object sender, EventArgs e)
{
UpdateText();
}
void UpdateText()
{
var diff = endTime.Subtract(DateTime.Now);
if (diff.TotalSeconds > 0)
label1.Text = string.Format("{0:D2}:{1:D2}:{2:D2}",
diff.Hours, diff.Minutes, diff.Seconds);
else
{
this.Text = "00:00:00";
timer.Enabled = false;
}
}
I wouldn't muck about with timers. I'd use Microsoft's Reactive Framework for this. Just NuGet "Rx-Winforms" to get the bits. Then you can do this:
Observable
.Create<string>(o =>
{
var now = DateTimeOffset.Now;
var end = now.AddMinutes(15.0);
return
Observable
.Interval(TimeSpan.FromSeconds(0.1))
.TakeUntil(end)
.Select(x => end.Subtract(DateTimeOffset.Now).ToString(#"mm\:ss"))
.DistinctUntilChanged()
.Subscribe(o);
})
.ObserveOn(this)
.Subscribe(x => label1.Text = x);
This will automatically create a countdown timer that will update the text in label1 with the following values:
14:59
14:58
14:57
14:56
14:55
14:54
...
00:02
00:01
00:00
If you want to stop this before the timer runs out the Subscribe method returns an IDisposable that you can just call .Dispose().
You should try to count the 15 minutes.
For example, if your using a Label (Label1) you should count it with a timer.
Just use a timer and count every tick (1000 milliseconds) +1
Timer1 has a +1 (declare a int as 0)
If the label reaches the number of seconds or minutes
(You can modify that with milliseconds), it stops the timer.

Frame animation in xamarin forms

I want to do frame animation and not sure should i use AnimationDrawable class for animation.
How do frame animation in Xamarin forms for Android. Is there any other approach? Simple example would be perfect.
I did trick just hiding and unhiding required elements. You could call from DoAnimation from any button click or smth else.
private void DoAnimation()
{
_timer = new System.Timers.Timer();
//Trigger event every second
_timer.Interval = 1000;
_timer.Elapsed += CheckStatus;
//count down 5 seconds
_countSeconds = 5000;
_timer.Enabled = true;
}
private void SpinAnimation()
{
switch (_letterShowState) {
case SomeStateStates.State1:
_pic1.IsVisible = false;
_pic2.IsVisible = true;
_pic3.IsVisible = false;
_letterShowState = SomeStateStates.State2;
break;
}
}
private void CheckStatus(object sender, System.Timers.ElapsedEventArgs e) {
_countSeconds--;
new System.Threading.Thread(new System.Threading.ThreadStart(() => {
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => {
SpinAnimation();
});
})).Start();
if (_countSeconds == 0)
{
_timer.Stop();
}
}

Creating a countdown timer,until a timer starts

I have a timer in a console app:
using System.Timers;
Timer Timer = new Timer();
I gave it an interval, and it does stuff at _timer_Elapsed method periodically:
Timer.Elapsed += _timer_Elapsed;
Timer.Enabled = true;
private static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
...
}
How can I create a second timer that counts down until this timer starts?
Create a second timer that elapses every second and use the following code to count down and a write message to the console.
#define COUNTDOWN_SECONDS 10
private int CountDownValue = COUNTDOWN_SECONDS;
private static void _timer2_Elapsed(object sender, ElapsedEventArgs e)
{
WriteConsoleMessage(CountDownValue--);
if (CountDownValue == 0)
{
// Stop timer2
// Start timer1
}
}
private static void WriteConsoleMessage(int Value)
{
if (Value < COUNTDOWN_SECONDS)
Console.CursorLeft = 0; // Reset cursor to start of the line
Console.Write(string.Format("{0} Seconds until timer starts", Value.ToString());
}
Heres how i did it:
public static int Interval = 5000;
public static int IntervalLeft = Interval;
Timer.Elapsed += _timer_Elapsed;
Timer.Enabled = true;
Timer.Interval = Interval;
CountDownTimer.Elapsed += _CountDowntimer_Elapsed;
CountDownTimer.Enabled = true;
CountDownTimer.Interval = 1000;
CountDownTimer.Start();
private static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
CountDownTimer.Stop();
Timer.Stop();
DOES THE JOB HERE
Timer.Start();
CountDownTimer.Start();
IntervalLeft = Interval;
}
private static void _CountDowntimer_Elapsed(object sender, ElapsedEventArgs e)
{
Zipper.ClearCurrentConsoleLine();
IntervalLeft = (IntervalLeft - 1000);
Console.Write("Starts in" + IntervalLeft/1000);
}
The first timer one stops the second timer when it elapses...

Timer Implementation not Running every 5 seconds as intended c#

I have the following timer implementation. But the timer is not running every 5 seconds as needed. How can make this run every 5 seconds. At present its running about once in 30 seconds.
private void button1_Click(object sender, RoutedEventArgs e)
{
msgsent = 0;
timer.Tick += timer_Tick;
timer.Interval = new TimeSpan(0, 0, 5);
bool isenable = timer.IsEnabled;
timer.Start();
}
private async void timer_Tick(object sender, object e)
{
if (geo == null)
{
geo = new Geolocator();
}
Geoposition posi = await geo.GetGeopositionAsync();
if (posi.Coordinate.Point.Position.Latitude <= 12.9227 && posi.Coordinate.Point.Position.Longitude >= 080.1320)
{
if (msgsent <=1)
{
msgsent = msgsent + 1;
ShowDialog(new MessageDialog("Your Bus has crossed xyz"));
}
}
}
I'll give you a hint. If you understand where each goes, then it should be clear. If not, you will once you get better.
// in the class definition
int msgsent;
Timer timer;
and
// in the constructor
timer = new Timer();
timer.Tick += timer_Tick;
timer.Interval = new TimeSpan(0, 0, 5);
and
// in the Button.Click event handler
timer.Start();
and
// in the Timer.Tick event handler
timer.Stop();
/* do your work here */
timer.Start();
There will be further issues when the user is clicking the button while you're doing your work, but that's beyond the scope of this question.

Timer won't tick

I have a Windows.Forms.Timer in my code, that I am executing 3 times. However, the timer isn't calling the tick function at all.
private int count = 3;
private timer;
void Loopy(int times)
{
count = times;
timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
count--;
if (count == 0) timer.Stop();
else
{
// Do something here
}
}
Loopy() is being called from other places in the code.
Try using System.Timers instead of Windows.Forms.Timer
void Loopy(int times)
{
count = times;
timer = new Timer(1000);
timer.Enabled = true;
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
throw new NotImplementedException();
}
If the method Loopy() is called in a thread that is not the main UI thread, then the timer won't tick.
If you want to call this method from anywhere in the code then you need to check the InvokeRequired property. So your code should look like (assuming that the code is in a form):
private void Loopy(int times)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
Loopy(times);
});
}
else
{
count = times;
timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
}
I am not sure what you are doing wrong it looks correct, This code works: See how it compares to yours.
public partial class Form1 : Form
{
private int count = 3;
private Timer timer;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Loopy(count);
}
void Loopy(int times)
{
count = times;
timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
count--;
if (count == 0) timer.Stop();
else
{
//
}
}
}
Here's an Rx ticker that works:
Observable.Interval(TimeSpan.FromSeconds(1))
.Take(3)
.Subscribe(x=>Console.WriteLine("tick"));
Of course, you can subscribe something more useful in your program.
you may have started the timer from another thread, so try invoking it from the correct thread.
for example, instead of:
timerX.start();
Use:
Invoke((MethodInvoker)delegate { timerX.Start(); });
Check if your timer in properties is enabled.
Mine was false and after setting to true it worked.
If you are using Windows.Forms.Timer then should use something like following.
//Declare Timer
private Timer _timer= new Timer();
void Loopy(int _time)
{
_timer.Interval = _time;
_timer.Enabled = true;
_timer.Tick += new EventHandler(timer_Elapsed);
_timer.Start();
}
void timer_Elapsed(object sender, EventArgs e)
{
//Do your stuffs here
}
If you use some delays smaller than the interval inside the timer, the system.timer will execute other thread and you have to deal with a double thread running at the same time. Apply an InvokeRequired to control the flow.

Categories