C# repeat button action - c#

I'm developing an app for a RFID reader. I have a button with the following action:
private void btnWrite_Click(object sender, EventArgs e)
{
this.CheckPort = true;
this.DetectCOMPort();
bool readerOK = this.IsReaderConnected(this.lblCom.Text);
bool flag = !readerOK;
if (flag)
{
this.CheckPort = true;
this.DetectCOMPort();
}
else
{
byte[] raspunsCitire = this.CitesteTag(this.lblCom.Text);
flag = raspunsCitire == null;
if (flag)
{
MessageBox.Show("The label couldn't be read!");
}
else
{
string scrisInTag = this.FormateazaCitire(raspunsCitire);
string[] campuriScrise = this.DecompileazaMesaj(scrisInTag, '|');
this.btnValid.Enabled = true;
this.txtEvenim.Enabled = true;
this.txtEvenim.Text = campuriScrise[0];
this.txtNume.Enabled = true;
this.txtNume.Text = campuriScrise[1];
this.txtPrenume.Enabled = true;
this.txtPrenume.Text = campuriScrise[2];
this.txtComp.Enabled = true;
this.txtComp.Text = campuriScrise[3];
this.txtFunc.Enabled = true;
this.txtFunc.Text = campuriScrise[4];
this.txtTit.Enabled = true;
this.txtTit.Text = campuriScrise[5];
this.Refresh();
}
}
}
What I want is the reading of the label to repeat every 2 seconds instead of displaying the MessageBox.Show("The label couldn't be read!");.
For the other case, when a label it's read I want this process to stop for let's say 20 seconds and after 20 seconds to start reading again at avery 2 seconds.
It is possible to do that somehow?
Thank you in advance!

Have you looked into timer control?
Timer timer = new Timer();
timer.Tick += new EventHandler(timer_Tick); // Everytime timer ticks, timer_Tick will be called
timer.Interval = (1000) * (10); // Timer will tick evert 10 seconds
timer.Enabled = true; // Enable the timer
timer.Start();

Related

CountDown is Not Working Correctly in Xamarin

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;
}

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();
}
}

C# Reset a countdown timer-DispatcherTimer- in windows store app

I'm a C# newbie_and in programming in general_ and Ι'm trying to build a math quiz app with a countdown timer.
I generate an equation each time the user clicks the start button and I give him a max 60 seconds to answer. The user answers -whether his answer is wrong or right doesn't matter_ and can he/she can click again for a new equation. So I want the timer to reset each time the user is shown a new random equation. So far I've only managed to reset this when the 60sec timespan elapses but even that is not working properly, sometimes it displays 59 or 58 secs instead of 60.
So far reading other questions has't helped me much and the timer confuses me. I also accept suggestions to make my code simpler and more elegant.
Here is my code:
EquationView.xaml.cs
public sealed partial class EquationView : Page
{
DispatcherTimer timer = new DispatcherTimer();
int tick = 60;
int result;
public EquationView()
{
this.NavigationCacheMode = NavigationCacheMode.Enabled;
this.InitializeComponent();
}
private void startButton_Click(object sender, RoutedEventArgs e)
{
// Once clicked then disabled
startButton.IsEnabled = false;
// Enable buttons required for answering
resultTextBox.IsEnabled = true;
submitButton.IsEnabled = true;
var viewModel = App.equation.GenerateEquation();
this.DataContext = viewModel;
result = App.equation.GetResult(viewModel);
timer.Interval = new TimeSpan(0, 0, 0, 1);
//timer.Tick += new EventHandler(timer_Tick);
timer.Tick += timer_Tick;
timer.Start();
DateTime startTime = DateTime.Now;
// Reset message label
if (message.Text.Length > 0)
{
message.Text = "";
}
// Reset result text box
if (resultTextBox.Text.Length > 0)
{
resultTextBox.Text = "";
}
}
private void timer_Tick(object sender, object e)
{
Countdown.Text = tick + " second(s) ";
if (tick > 0)
tick--;
else
{
Countdown.Text = "Times Up";
timer.Stop();
submitButton.IsEnabled = false;
resultTextBox.IsEnabled = false;
startButton.IsEnabled = true;
tick = 60;
}
}
private void submitButton_Click(object sender, RoutedEventArgs e)
{
timer.Stop();
submitButton.IsEnabled = false;
resultTextBox.IsEnabled = false;
if (System.Text.RegularExpressions.Regex.IsMatch(resultTextBox.Text, "[^0-9]"))
{
MessageDialog msgDialog = new MessageDialog("Please enter only numbers.");
msgDialog.ShowAsync();
resultTextBox.Text.Remove(resultTextBox.Text.Length - 1);
//Reset buttons to answer again
submitButton.IsEnabled = true;
resultTextBox.IsEnabled = true;
timer.Start();
}
else
{
try
{
int userinput = Int32.Parse(resultTextBox.Text);
if (userinput == result)
{
message.Text = "Bingo!";
App.player.UpdateScore();
startButton.IsEnabled = true;
}
else
{
message.Text = "Wrong, sorry...";
startButton.IsEnabled = true;
}
}
catch (Exception ex)
{
MessageDialog msgDialog = new MessageDialog(ex.Message);
msgDialog.ShowAsync();
submitButton.IsEnabled = true;
resultTextBox.IsEnabled = true;
timer.Start();
}
}
}
It seems to me that you have at least two significant problems here. One is that your timer will likely give the user more than 60 seconds, due to the inaccuracy in the Windows thread scheduler (i.e. each tick will occur at slightly more than 1 second intervals). The other (and more relevant to your question) is that you don't reset the tick value to 60 except when the timer has elapsed.
For the latter issue, it would be better to simply reset your countdown value when you start the timer, rather than trying to remember everywhere that you stop it.
To fix that and the first issue, get rid of the tick field altogether and change your code to look more like this:
static readonly TimeSpan duration = TimeSpan.FromSeconds(60);
System.Diagnostics.Stopwatch sw;
private void startButton_Click(object sender, RoutedEventArgs e)
{
// Once clicked then disabled
startButton.IsEnabled = false;
// Enable buttons required for answering
resultTextBox.IsEnabled = true;
submitButton.IsEnabled = true;
var viewModel = App.equation.GenerateEquation();
this.DataContext = viewModel;
result = App.equation.GetResult(viewModel);
sw = System.Diagnostics.Stopwatch.StartNew();
timer.Interval = new TimeSpan(0, 0, 0, 1);
timer.Tick += timer_Tick;
timer.Start();
// Reset message label
if (message.Text.Length > 0)
{
message.Text = "";
}
// Reset result text box
if (resultTextBox.Text.Length > 0)
{
resultTextBox.Text = "";
}
}
private void timer_Tick(object sender, object e)
{
if (sw.Elapsed < duration)
{
Countdown.Text = (int)(duration - sw.Elapsed).TotalSeconds + " second(s) ";
}
else
{
Countdown.Text = "Times Up";
timer.Stop();
submitButton.IsEnabled = false;
resultTextBox.IsEnabled = false;
startButton.IsEnabled = true;
}
}
This way, it won't matter exactly when the tick event happens, the code will still correctly compute the actual time remaining and use that for the display and to tell whether the time is up.

Timer tick is not triggered

I check a condition on my form_load event whether the form window should be closed or not. If so, a timer with an interval of 3000 will be started and after the tick, the form should be closed. When I check my debugger, even though the condition returns true, the debugger jumps over my timer.Start() method and my timer is never ticked.
I have defined the timer in my class as System.Windows.Forms.Timer timer; and this is how I am initiating it:
timer = new System.Windows.Forms.Timer();
this.timer.Enabled = true;
this.timer.Interval = 3000;
this.timer.Tick += new System.EventHandler(this.timer_Tick_1);
The tick event:
private void timer_Tick_1(object sender, EventArgs e)
{
this.Close();
}
And the condition is as simple as:
if (closeWindow)
timer.Start();
And trust me, the closeWindow returns true.
P.s. Strangely enough, this timer used to work. I know I have it messed up somewhere perhaps. But I do not know where.
Update: the form_load event
private void FormMain_Load(object sender, EventArgs e)
{
metroLabelBuild.Text = args["name"] + " " + args["action"];
if (CheckArguments(args, 18))
{
try
{
campaignRecipientsFileLocation = args["recipientsfile"].Trim();
campaignName = args["name"].Trim();
campaignDescription = args["description"].Trim();
campaignAction = args["action"].Trim();
campaignOutputFormat = args["outputformat"].Trim();
campaignType = args["type"].Trim().ToLower();
campaignDelimiter = args["delimeter"].Trim();
campaignOutputPath = args["outputpath"].Trim();
campaignFileName = args["filename"].Trim();
campaignId = Convert.ToInt64(args["id"].Trim());
campaignFixedCost = Convert.ToInt32(args["fixedcost"]);
campaignVariableCost = Convert.ToInt32(args["variablecost"]);
campaignControlGroup = Convert.ToInt32(args["controlgroup"]);
campaignFtpId = Convert.ToInt64(args["ftpid"].Trim());
campaignHasSpyList = (args["hasspylist"].ToLower().Equals("true") || args["hasspylist"].Equals("1")) ? true : false;
closeWindow = (args["closewindow"].ToLower().Equals("true") || args["closewindow"].Equals("1")) ? true : false;
campaignShouldUploadToFTP = (args["shoulduploadtoftp"].ToLower().Equals("true") || args["shoulduploadtoftp"].Equals("1")) ? true : false;
}
catch
{
listBoxMessages.Items.Add("Error preparing the arguments.");
continueProcess = false;
this.Close();
}
finally
{
logger = new Logger(loggerEnabled, cs);
fh = new FileHelper(logger);
rh = new RecipientHelper(logger);
dbh = new DatabaseHelper(logger, cs);
if (continueProcess)
{
InsertCampaignRun("Running");
RunCampaign();
if (closeWindow)
timer.Start();
}
}
}
else
{
if (closeWindow)
timer.Start();
}
}

Categories