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.
Related
I am using Windows Forms (.NET Framework) and am trying to make a picture box move a cross a screen.
I have tried using timers and this while loop but the image (it's supposed to be a plane) does not appear in the case of the while loop and the use of timers makes it difficult to remove past picture Boxes so they appear to generate a sequence of planes. How can I accomplish this?Does it have something to do with Sleep()?
private void Button1_Click(object sender, EventArgs e)
{
//airplane land
//drawPlane(ref locx, ref locy);
//timer1.Enabled = true;
while (locx > 300)
{
var picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(30, 30),
Location = new System.Drawing.Point(locx, locy),
Image = Properties.Resources.plane2, //does not appear for some reason
};
this.Controls.Add(picture);
Thread.Sleep(500);
this.Controls.Remove(picture);
picture.Dispose();
locx = locx - 50;
}
You can use a "Timer" to change the position of the PictureBox regularly.
Here is a simple demo that using Timer Class you can refer to.
public partial class Form1 : Form
{
private System.Timers.Timer myTimer;
public Form1()
{
InitializeComponent();
myTimer = new System.Timers.Timer(100);
myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
myTimer.AutoReset = true;
myTimer.SynchronizingObject = this;
}
private void myTimer_Elapsed(object sender, ElapsedEventArgs e)
{
pictureBox1.Location = new Point(pictureBox1.Location.X + 1, pictureBox1.Location.Y);
}
private void btStart_Click(object sender, EventArgs e)
{
myTimer.Enabled = true;
}
}
The result,
Using C#, windows form.
I am trying to make the program automatically select next item on combo box every x seconds and once it reaches the last one, it goes back to the first one on list. i got pretty much everything minus auto combo box selection part. :(
help please.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//pictureBox1.Image = Image.FromFile(#"Z:\DSCF1661.jpg");
DirectoryInfo test = new DirectoryInfo(#"C:\temp");//Assuming Test is your Folder
FileInfo[] Files = test.GetFiles("*.pdf"); //Getting Text files
comboBox1.DataSource = Files;
comboBox1.DisplayMember = "Name";
timerset();
}
public void axSetting()
{
axAcroPDF1.setShowToolbar(false);
axAcroPDF1.setView("FitH");
axAcroPDF1.setPageMode("none");
axAcroPDF1.setLayoutMode("SinglePage");
axAcroPDF1.Show();
}
private void comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
axAcroPDF1.LoadFile(#"C:\temp\" + comboBox1.Text);
axAcroPDF1.src = #"C:\temp\" + comboBox1.Text;
axSetting();
}
//private System.Windows.Forms.Timer timer1;
public void comboBoxSelect()
{
if (comboBox1.SelectedIndex < comboBox1.Count) // this part... :(
{
comboBox1.SelectedIndex += 1;
}
else
{
comboBox1.SelectedIndex = 0;
}
}
public void timerset()
{
timer1 = new System.Windows.Forms.Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 5000; // in miliseconds
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
comboBoxSelect();
}
This should work:
if(combobox.SelectedIndex < (combobox.Items.Count -1))
{
combobox.SelectedIndex += 1;
}
else
{
combobox.SelectedIndex = 0;
}
I want to use the ProgressBar and run it from 100% to 0% within 2 seconds. I have written the following function but it does not seem to run properly. Please help! Thank you!
private async void progessbar()
{
for (iValue = 100; iValue >= 0; iValue--)
{
pbTime.Value = iValue;
await Task.Delay(20);
}
}
If you want to animate your progress bar smoothly, you should use a storyboard:
private void AnimateProgressBar()
{
var storyboard = new Storyboard();
var animation = new DoubleAnimation { Duration = TimeSpan.FromSeconds(2), From = 100, To = 0, EnableDependentAnimation = true };
Storyboard.SetTarget(animation, this.ProgressBar);
Storyboard.SetTargetProperty(animation, "Value");
storyboard.Children.Add(animation);
storyboard.Begin();
}
You are changing toolbar multiple times in the same Windows event. Windows updates GUI later when it is idle. Thus you probably see your toolbar jump from 0 to 100% after 2 second wait.
Just add timer to your control, set it when ready to start and do incremental updates.
// In your designer:
this.timer.Enabled = false;
this.timer.Interval = 200;
this.timer.Tick += new System.EventHandler(this.timer_Tick);
// when starting the progress:
pbTime.Value = 0
this.timer.Enabled = true;
private void timer_Tick(object sender, EventArgs e)
{
if (pbTime.Value < 100)
pbTime.Value += 10;
}
I hope this helps
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, System.EventArgs e)
{
// Start the BackgroundWorker.
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
/*Your main code*/
for (int i = 1; i <= 100; i++)
{
// Wait 20 milliseconds.
Thread.Sleep(20);
// Report progress.
backgroundWorker1.ReportProgress(i);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Change the value of the ProgressBar to the BackgroundWorker progress.
progressBar1.Value = e.ProgressPercentage;
// Set the text.
this.Text = e.ProgressPercentage.ToString();
}
}
}
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.
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) {
}