In my application I need a progress bar to display the progress of a plant growing. This would be the code:
private static Timer farmProgress;
internal void initFarmProgTimer( int step, int max = 100 )
{
farmProgress = new Timer();
farmProgress.Tick += new EventHandler(farmProgress_Tick);
farmProgress.Interval = step; // in miliseconds
farmProgress.Start();
}
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
plantProgressBar.Value = increment;
}
}
Here the call of the initFarmProgTimer function:
public static System.Threading.Timer growTimer;
public static void InitGrowTimer(int time, string name)
{
growTimer = new System.Threading.Timer(growTimer_Finished, null, time, Timeout.Infinite);
plantActive = true;
Menu menu = new Menu();
menu.initFarmProgTimer(time / 100);
}
Note that the class where this function is called from is NOT a form but the class where the function is defined IS a form.
Does anybody know what my error is?
edit
here is the call for the InitGrowTimer function
switch ( index )
{
case 0:
currentPlant = wheat.name;
plantQ = printPlantDatas("wheat");
if (plantQ == true)
{
InitGrowTimer(wheat.time, wheat.name);
wheat.planted++;
}
break;
}
You are setting the value to the progress bar which will only set the progress to the current value. You have to increment it rather. I have added the pluss (+) sign for you
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
plantProgressBar.Value += increment;
}
}
It is not clear to me what is on a Form and what isn't but assuming this is on the Form:
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
plantProgressBar.Value = increment;
}
}
Change it to this so that you update the control from the UI thread:
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
this.Invoke(new Action(() => {
plantProgressBar.Value = increment;
}));
}
}
Update
My answer is wrong, I didn't expect this, but I created a Forms application and this worked fine to increment the progressbar:
public partial class Form1 : Form
{
private Timer farmProgress;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
farmProgress = new Timer();
farmProgress.Tick += farmProgress_Tick;
farmProgress.Interval = 1000; // in miliseconds
farmProgress.Start();
}
void farmProgress_Tick(object sender, EventArgs e)
{
progressBar1.Value++;
}
}
Related
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int A = 0;
private void timer1_Tick(object sender, EventArgs e)
{
A++;
if (A == 30)
{
A--;
}
textBox1.Text = A.ToString();
}
}
}
Just store the direction you're going and flip it when you reach the limits:
int A = 0;
int direction = 1;
private void timer1_Tick(object sender, EventArgs e)
{
A += direction;
if (A == 30 || A == 0)
{
direction = -direction;
}
textBox1.Text = A.ToString();
}
In my form I have one button and one label, and in my class I have one timer and it should start with timer.Start();
I need help because I need to start the timer in my form with one button1_Click but I canĀ“t start the timer and where I should have the elapsed event in form or in class timer?
So when I click in the start button in my Form the timer should start, in my Timer.cs, and label in form should show timer time
Timer.CS
public class Timer
{
public string TimerType { get; set; }
public Timer PersonUnlimitedTimer { get; set; }
public enum TypeTimer { Unlimited, Countdown, Limited}
int timervalue;
int minute = 60;
int second = 0;
//Valor a ser alterado pelo user
int final = 1;
public Timer()
{
timervalue = final * minute;
PersonUnlimitedTimer = new Timer();
PersonUnlimitedTimer.Interval = 1000;
PersonUnlimitedTimer.Elapsed += _PersonUnlimitedTimer_Elapsed;
PersonUnlimitedTimer.Start();
}
public Timer(TypeTimer s1)
{
switch (s1)
{
case TypeTimer.Unlimited:
second++;
TimeSpan unlimited_timer = new TimeSpan(0, 0, second);
TimerTime = unlimited_timer.ToString();
break;
case TypeTimer.Countdown:
if (second != timervalue)
{
timervalue--;
TimeSpan countdown_timer = new TimeSpan(0, 0, timervalue);
TimerTime = countdown_timer.ToString();
}
else
{
PersonUnlimitedTimer.Stop();
}
break;
case TypeTimer.Limited:
if (second != timervalue)
{
second++;
TimeSpan limited_timer = new TimeSpan(0, 0, second);
TimerTime = limited_timer.ToString();
}
else
{
PersonUnlimitedTimer.Stop();
}
break;
default:
break;
}
}
public void _PersonUnlimitedTimer_Elapsed(object sender, ElapsedEventArgs e)
{
second++;
TimeSpan unlimited_timer = new TimeSpan(0, 0, second);
TimerTime = unlimited_timer.ToString();
}
}
and this is my form
namespace Time
{
public partial class Timers : Form
{
Timer timer;
public Timers()
{
InitializeComponent();
}
public Timers(Timertimer): this()
{
this.timer= timer;
timer.PersonUnlimitedTimer.Elapsed += PersonUnlimitedTimer_Elapsed;
}
void PersonUnlimitedTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
lblTimerTime.Text = timer.TimerTime;
}
private void Timers_Load(object sender, EventArgs e)
{
}
private void btnStart_Click(object sender, EventArgs e)
{
timer.PersonUnlimitedTimer.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
timer.PersonUnlimitedTimer.Stop();
}
private void btnReset_Click(object sender, EventArgs e)
{
timer.PersonUnlimitedTimer.Stop();
lblTimerTime.Text = "00:00:00";
}
}
}
The problem is that the numericupdown doesn't change types of speed for fast and slow. Basically it would speed up whether the value is positive or negative and if I take it to back to zero it will crash. I am now trying to make an if loop inside of the numericupdown for TickCounter.
Here it is:
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Text = "AAAAAAA AAAAAAA #########";
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
TickCounterLabel.Text = "The timer has started";
tPeriodic.Enabled = true;
}
else
{
TickCounterLabel.Text = "The timer has ended";
tPeriodic.Enabled = false;
}
}
private void TickCounter_ValueChanged(object sender, EventArgs e)
{
**TickCounter.Value = TickCount;
if (TickCount >= 0)
tPeriodic.Interval = 1000 / Convert.ToInt32(TickCounter.Value * TickCounter.Value);
else if (TickCount <= 0)
tPeriodic.Interval = 1000 * Convert.ToInt32(TickCounter.Value * TickCounter.Value);
else if (TickCount == 0)
tPeriodic.Interval = Convert.ToInt32(TickCounter.Value * TickCounter.Value);**
}
private void tPeriodic_Tick(object sender, EventArgs e)
{
tickCount += 1;
lTickCount.Text = tickCount.ToString();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
public int tickCount { get; set; }
public int X { get; set; }
private void TickCounterLabel_Click(object sender, EventArgs e)
{
}
public int TickCount { get; set; }
}
}
Should I use another type of loop or am I just writing this wrong? When I try to change the value now it just crashes and the doesn't change at all.
Does anyone know how this can be accomplished? Also, should else if (TickCount == 0) be different if I don't want to have any change at all?
I guess it is because of divide by zero.
In the code of "TickCounter_ValueChanged", for TickCount=0, it just gets into the first "if" block and will cause the exception.
You need to use "if-else" conditions in a correct way.
private void TickCounter_ValueChanged(object sender, EventArgs e)
{
if (TickCounter.Value > 0)
tPeriodic.Interval = 1000 / Convert.ToInt32(TickCounter.Value * TickCounter.Value);
else if (TickCounter.Value < 0)
tPeriodic.Interval = 1000 * Convert.ToInt32(TickCounter.Value * TickCounter.Value);
else
tPeriodic.Interval = 1000;
}
Please let me know whether it solves your problem.
My problem is that I want the form still display data when it increases but the form is blocked and I cannot do anything with it.
This is my code :
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
while (true)
for (int i = 1; i < 11; i++)
richTextBox1.Text += "here" + i + "/n";
}
}
}
How I can prevent form from blocking?
private void Form1_Load(object sender, EventArgs e)
{
BackgroundWorker BWorker = new BackgroundWorker();
BWorker.DoWork += BWorker_DoWork;
BWorker.RunWorkerAsync();
}
void BWorker_DoWork(object sender, DoWorkEventArgs e)
{
// while(true) is meaningless.
for (int i = 1; i < 11; i++)
{
Action UpdateUI = () => { richTextBox1.Text += "here" + i + "/n"; };
this.BeginInvoke(UpdateUI);
}
}
Split your working cycle into steps by utilizing timer
private int _workStep;
private void button1_Click(object sender, EventArgs e)
{
_workStep = 0;
timerWork.Start();
}
private void timerWork_Tick(...)
{
switch(workStep)
{
case 0:
... // do something
if(something)
_workStep = 1;
case laststep:
timerWork.Stop();
}
}
or put work into thread (by using Thread, BackgroundWorker or Task), but then you must use Invoke/BeginInvoke when updating something in the user interface (accessing controls).
You can do this to get a responsive ui
delegate void DisplayInvoker(string text);
private void DisplayinRichTextbox(string text)
{
if (this.InvokeRequired)
this.BeginInvoke(new DisplayInvoker(DisplayinRichTextbox), text);
return;
}
richTextBox1.Text += text;
}
private void button1_Click(object sender, EventArgs e)
{
// some synchronization would have to be done kill old
// pool threads when the button is hit again
//
ThreadPool.QueueUserWorkItem((x) =>
{
while (true)
for (int i = 1; i < 11; i++)
DisplayinRichTextbox("here" + i + "/n");
});
}
I need to draw some things on the screen for only 1 frame.
Things such as a line of text.
I tried to achieve this with moving windows, but I failed. I cannot get them to show for only 1 frame (8-16 msec), either by showing/hiding or moving in and out of place.
Is there any way to do this?
(Urgh, for the curious, I'm doing this for someone else, so rationalizing over the reason why this needs to be done is useless.)
Edit: Last thing I tried:
public partial class Form2 : Form
{
static Random rand = new Random();
public void ShowString(string s)
{
this.label1.Text = s; // Has .AutoSize = true
this.Size = this.label1.Size;
var bnds = Screen.PrimaryScreen.WorkingArea;
bnds.Size -= this.Size;
this.Location = new Point(rand.Next(bnds.X, bnds.Right), rand.Next(bnds.Y, bnds.Bottom));
}
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (Location.X != -10000 && Location.Y != -10000)
{
Location = new Point(-10000, -10000);
timer1.Interval = Program.interval; // How long to wait before showing two things.
}
else
{
timer1.Interval = Program.delay; // For how long to show.
ShowString("just something to test");
}
}
}
And before that:
public partial class Form2 : Form
{
static Random rand = new Random();
public void ShowString(string s)
{
this.label1.Text = s; // Has .AutoSize = true
this.Size = this.label1.Size;
var bnds = Screen.PrimaryScreen.WorkingArea;
bnds.Size -= this.Size;
this.Location = new Point(rand.Next(bnds.X, bnds.Right), rand.Next(bnds.Y, bnds.Bottom));
}
public Form2()
{
InitializeComponent();
timer1.Interval = Program.interval;
}
private void Form2_Load(object sender, EventArgs e)
{
timer1.Enabled = true;
}
private void Form2_Move(object sender, EventArgs e)
{
if (Location.X != -10000 && Location.Y != -10000)
{
Thread.Sleep(Program.delay); // Dirty cheat, but I was just trying.
this.Location = new Point(-10000, -10000);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
ShowString("just something to test");
}
}