I read a separate article here that explained how to make a simple text animation in a windows form application. The Code below worked perfectly in a form. However, I am creating a Windows Store App and it does not work. The timer class is not recognized, and because of this, the code does not work. Do I need to make a timer class, or is there some other class that I should use? If I need to make a timer class, how would I do that? Thank you.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
t = new Timer();
t.Interval = 40;
t.Tick += new EventHandler(t_Tick);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
string stuff = "This is some text that looks like it is being typed.";
int pos = 0;
Timer t;
void t_Tick(object sender, EventArgs e)
{
if (pos < stuff.Length)
{
textBox1.AppendText(stuff.Substring(pos, 1));
++pos;
}
else
{
t.Stop();
}
}
private void button1_Click_1(object sender, EventArgs e)
{
pos = 0;
textBox1.Clear();
t.Start();
}
}
The WinForms Timer isn't available in Windows Store Apps. You can use DispatcherTime instead.
dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
void dispatcherTimer_Tick(object sender, object e) {
}
Related
I need a simple timer that prints the countdown in a TextBlock in my UWP app. I was suggested to use DispatcherTimer. That's my code.
private void MainButton_Click(object sender, RoutedEventArgs e)
{
dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += DispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(1000);
dispatcherTimer.Start();
}
private int Seconds;
private void DispatcherTimer_Tick(object sender, DispatcherTimer e)
{
Seconds++;
MainTextBlock.Text = Seconds.ToString();
}
Anyway, I see this error and I cannot figure it out.
Any help in finding a better solution for my needs is welcome, too.
Please edit above DispatcherTimer_Tick like the following. You could press + = Tab key to generate evet handle method automatically.
private void DispatcherTimer_Tick(object sender, object e)
{
}
Here I have a chart (graph1) that normally should add a random point every 1second. but it doesn't... I tried to find out what the problem is but here I don't have anymore ideas...
The timer is started, label1 change every seconds but the chart doesn't change... with button one when I click it adds a new point.
what did I miss? please help... thanks a lot.
namespace Test_Chart1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true;
graph1.ChartAreas[0].AxisX.ScaleView.Size = 40;
System.Timers.Timer _Timer1s = new System.Timers.Timer(1000); //object
_Timer1s.Elapsed += _Timer1sElapsed; //event in object
_Timer1s.Start(); //start counting
}
private void _Timer1sElapsed(object sender, EventArgs e)//Timer each 100ms
{
if (label1.BackColor == Color.Red)
{
label1.BackColor = Color.Blue;
PutValueInGraph1();
}
else label1.BackColor = Color.Red;
}
private void button1_Click(object sender, EventArgs e)
{
PutValueInGraph1();
}
private void PutValueInGraph1()
{
graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true;
graph1.ChartAreas[0].AxisX.ScaleView.Size = 100;
Random Rand_Value = new Random();
int ValueToAdd = Rand_Value.Next(1, 100);
listBox1.Items.Add(ValueToAdd.ToString());
graph1.Series["Data1"].Points.AddY(ValueToAdd);
if (graph1.ChartAreas[0].AxisX.Maximum-10 > graph1.ChartAreas[0].AxisX.ScaleView.Size)
{
graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum);
graph1.Series["Data1"].Points.RemoveAt(0);
}
}
}
}
ok here is the new one:
public partial class Form1 : Form
{
static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
public Form1()
{
InitializeComponent();
myTimer.Tick += new EventHandler(TimerEventProcessor);
myTimer.Interval = 1;
}
private void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
{
Random Rand_Value = new Random();
int ValueToAdd = Rand_Value.Next(1, 100);
listBox1.Items.Add(ValueToAdd.ToString());
graph1.Series["Data1"].Points.AddY(ValueToAdd);
if (graph1.ChartAreas[0].AxisX.Maximum - 10 > graph1.ChartAreas[0].AxisX.ScaleView.Size)
{
graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum);
graph1.Series["Data1"].Points.RemoveAt(0);
}
}
private void btn_Start_Click_1(object sender, EventArgs e)
{
graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true;
graph1.ChartAreas[0].AxisX.ScaleView.Size = 100;
myTimer.Start();
BlinkLed.BackColor = Color.YellowGreen;
}
private void btn_Stop_Click(object sender, EventArgs e)
{
myTimer.Stop();
BlinkLed.BackColor = Color.AliceBlue;
}
}
Do you think it's better?
What about the changing thread?
If I had a button:
private void PutValueInGraph1()
{
Random Rand_Value = new Random();
int ValueToAdd = Rand_Value.Next(1, 100);
listBox1.Items.Add(ValueToAdd.ToString());
graph1.Series["Data1"].Points.AddY(ValueToAdd);
if (graph1.ChartAreas[0].AxisX.Maximum-10 > graph1.ChartAreas[0].AxisX.ScaleView.Size)
{
graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum);
graph1.Series["Data1"].Points.RemoveAt(0);
}
}
private void button1_Click(object sender, EventArgs e)
{//try to raise exception
PutValueInGraph1();
}
and I change the event like this:
private void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
{//try to raise exception
PutValueInGraph1();
}
The data input accelerate when I'm started the timer and I click all the time on the button1.
Why is there no exception as tom_imk said??
because we can access the same function at the same time....?
Thanks for your answers.
I tried below sample code and it is working fine for me.
public Form7()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
chart1.ChartAreas[0].AxisX.Maximum = 100;
chart1.ChartAreas[0].AxisX.Minimum = 0;
chart1.ChartAreas[0].AxisX.Interval = 1;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
Random Rand_Value = new Random();
int ValueToAdd = Rand_Value.Next(1, 100);
chart1.Series[0].Points.AddY(ValueToAdd);
}
I'm surprised you didn't get an exception. You are manipulating UI elements outside the UI thread, something you musn't do, ever.
Refer to the answer in this question:
How to update the GUI from another thread in C#?
EDIT:
To make clear why the timerelapsed method does not run on the UI thread: It's simply the wrong class that is used here. So the easy solution would be to not created a System.Timers.Timer in the Form-constructor but to drop a timer on the form in the form designer and use that instead. The solution by sowjanya attaluri should be marked as the correct answer.
I am confuse at this one, the windows form called "Contact" sometimes called twice after the "Welcome Screen" and sometimes it ("Contact") is called once only. I am pretty sure that I called the form once only.
Here is the code that I am using:
The form below "WelcomeScreen" is the first one called when run the program:
public partial class WelcomeScreen : Form
{
int timeLeft = 5;
Timer _timer = new Timer();
BackgroundWorker _backgroundWorker = new BackgroundWorker();
public WelcomeScreen()
{
InitializeComponent();
_backgroundWorker.WorkerReportsProgress = true;
_backgroundWorker.DoWork += BackgroundWorker_DoWork;
_backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
_timer.Interval = 1000;
_timer.Tick += Timer_Tick;
}
void WelcomeScreen_Load(object sender, EventArgs e)
{
_backgroundWorker.RunWorkerAsync();
}
void Timer_Tick(object sender, EventArgs e)
{
timeLeft--;
if (timeLeft <= 0)
{
_timer.Stop();
this.Hide();
Contact _contact = new Contact();
_contact.ShowDialog();
this.Close();
}
}
void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
if (e.ProgressPercentage <= 300)
{
_timer.Start();
this.label3.Text = "Completed ( " + timeLeft + " ) ";
this.label4.Text = string.Empty;
}
}
void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 300; i++)
{
_backgroundWorker.ReportProgress(i);
System.Threading.Thread.Sleep(200);
}
}
The form below "Contact" is called after the "WelcomeScreen":
public partial class Contact : Form
{
const int CP_NOCLOSE_BUTTON = 0x200;
public Contact()
{
InitializeComponent();
}
void Contact_Load(object sender, EventArgs e)
{
SystemManager.SoundEffect();
}
void button1_Click(object sender, EventArgs e)
{
this.Hide();
Loading _loading = new Loading();
_loading.ShowDialog();
this.Close();
}
protected override CreateParams CreateParams
{
get
{
CreateParams myCp = base.CreateParams;
myCp.ClassStyle = myCp.ClassStyle | CP_NOCLOSE_BUTTON;
return myCp;
}
}
I appreciate your answer!
Thank you
It looks like your Timer is causing the issue, by firing multiple times...
You have this condition inside your timer code:
if (timeLeft <= 0)
And the line before is timeLeft--. After timeLeft becomes 0, it will continue getting smaller (-1, -2, etc) and the form will be shown each time.
A quick fix is to either change the condition to timeLeft == 0 or change the type of timeLeft to a uint. Of course, these are both hacks. The correct fix would be to fix your code to stop the timer from firing when required.
So, this seems to be a common question but I can't seem to figure out a way to do this. I have a C# Form application that goes out to an imap client and processes the emails. I want to have a timer formatted like "08:45" (for 8 minutes and 45 seconds) displayed on the form to let the user know how long it has been since they clicked the button to start the process.
I want the timer to stop once my process ends obviously.
private void btn_ImportEmail_Click(object sender, EventArgs e)
{
this.timer = new System.Timers.Timer();
this.lblTimer = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize) (this.timer)).BeginInit();
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimerElapsed);
//connect to email and download messages...
this.timer.Enabled = true;
this.timer.SynchronizingObject = this;
timer.Interval = 1000;
timer.Start();
for (int I = 0 ; I <= messages.count() - 1; I++)
{
//process emails
}
timer.EndInit();
}
private void timer1_Tick(object sender, EventArgs e)
{
lblTimer.Text = DateTime.Now.ToString("mm:ss");
}
private void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
lblTimer.Text = DateTime.Now.ToString("mm:ss");
// lblTimer.Text = string.Format("{0:mm:ss}", DateTime.Now);
}
The following SO Q/A might answer your question...
Display the running time of part of a program in a label
I would recommend changing the format to your needs.
The first thing that I see is that you are using DateTime.Now which will give you the current minutes and seconds, not elapsed minutes and seconds. The second thing and the main thing is that since you are processing your emails in your main UI's thread you are preventing your label from being updated, you would be better off looking at using a background worker instead.
Edit based on Idle_Mind's comment added DateTime Object instead of counter.
public partial class Form1 : Form
{
BackgroundWorker bgw = new BackgroundWorker();
Timer timer = new Timer();
DateTime startTime;
public Form1()
{
InitializeComponent();
timer.Interval = 1000;
timer.Tick += timer_Tick;
bgw.DoWork += bgw_DoWork;
bgw.RunWorkerCompleted+=bgw_RunWorkerCompleted;
}
void timer_Tick(object sender, EventArgs e)
{
label1.Text =((TimeSpan)DateTime.Now.Subtract(startTime)).ToString("mm\\:ss");
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
timer.Stop();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
for (int I = 0 ; I <= messages.count() - 1; I++)
{
//process emails
}
}
private void button1_Click(object sender, EventArgs e)
{
bgw.RunWorkerAsync();
startTime = DateTime.Now;
timer.Start();
}
}
I have four buttons that are called "ship1,ship2" etc.
I want them to move to the right side of the form (at the same speed and starting at the same time), and every time I click in one "ship", all the ships should stop.
I know that I need to use a timer (I have the code written that uses threading, but it gives me troubles when stopping the ships.) I don't know how to use timers.
I tried to read the timer info in MDSN but I didn't understand it.
So u can help me?
HERES the code using threading.
I don't want to use it. I need to use a TIMER! (I posted it here because it doesnt give me to post without any code
private bool flag = false;
Thread thr;
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
flag = false;
thr = new Thread(Go);
thr.Start();
}
private delegate void moveBd(Button btn);
void moveButton(Button btn)
{
int x = btn.Location.X;
int y = btn.Location.Y;
btn.Location = new Point(x + 1, y);
}
private void Go()
{
while (((ship1.Location.X + ship1.Size.Width) < this.Size.Width)&&(flag==false))
{
Invoke(new moveBd(moveButton), ship1);
Thread.Sleep(10);
}
MessageBox.Show("U LOOSE");
}
private void button1_Click(object sender, EventArgs e)
{
flag = true;
}
Have you googled Windows.Forms.Timer?
You can start a timer via:
Timer timer = new Timer();
timer.Interval = 1000; //one second
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.Start();
You'll need an event handler to handle the Elapsed event which is where you'll put the code to handle moving the 'Button':
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MoveButton();
}