I'd like to add a loop to:
private void button5_Click(object sender, EventArgs e)
{
}
This will run Form1 for 5 times with 3 second delay than close all, than do it again.
I'm using this code to open them manually;
Form1 form = new Form1();
form.Show();
And I need to stop the loop with;
private void button6_Click(object sender, EventArgs e)
{
}
I'm new to coding and if you can explain it with code examples I would be grateful.
Im not sure why you ever want this. But here is the way.
You need a Timer with interval of 3000 milliseconds (3 seconds) that will fire an Event at every interval. Inside that Event you will Open up forms and will close all the forms if 5 forms are opened.
Timer _timer = new Timer(); // This is the timer
List<Form> forms = new List<Form>(); // This will hold list of forms.
private void button1_Click(object sender, EventArgs e)
{
_timer.Enabled = !_timer.Enabled; // toggle event with this button.
}
private void Form1_Load(object sender, EventArgs e) // initialize timer with form load event
{
_timer.Interval = 3000; // set interval
_timer.Tick += OpenUpForm; // set event
}
private void OpenUpForm(object sender, EventArgs e) // this is the event that should be fired every 3 seconds
{
if (forms.Count == 5) // if forms reached 5 attempt to close all
{
// ForEach will perform this actions for every form in forms list
forms.ForEach(f =>
{
f.Close(); // close form
f.Dispose(); // free resources
});
forms.Clear(); // clear the list
return;
}
forms.Add(new Form()); // add a new form to list
forms.Last().Show(); // show the form
}
Note that this will just open empty forms. If you want to open specific form you should create a 5 copy of that and put them inside list. and just open and close them.
Related
I believe I have a misunderstanding about either how a lock works or how the System.Windows.Forms.Timer works in C#.
So I made a simple Windows Forms Application (.NET Framework) and I added a Timer and a Button to the Form from the Toolbox. The Button starts the Timer when clicked, and the Timer enters a lock on a dummy object and blocks it on the Tick event. For the Button's Click event I have the following method:
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
And for the Timer's Tick event I have this method:
readonly object lockObj = new object();
private void timer1_Tick(object sender, EventArgs e)
{
lock (lockObj)
{
MessageBox.Show("Entered the lock!");
MessageBox.Show("Exiting the lock...");
}
}
Everything else is left to default and there is no additional code.
I expected this program to show a single MessageBox with the text "Entered the lock!", then after I close it and also the following one with the message "Exiting the lock..." I thought the lock would be released and a queued up Tick event if any would acquire the lock, the process reapeating. Instead, the "Entered the lock!" MessageBox keeps opening multiple times without having to close it, as if every Tick event call enters the lock even if nobody releases it.
I tried to replicate this in a Console Application but with no luck. I'd appreciate a hint about what causes this problem so I know where to look into it.
Alternative code you can test in a Windows Forms Application:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Lock_Test_2
{
public partial class Form1 : Form
{
Timer timer1;
readonly object lockObj = new object();
public Form1()
{
InitializeComponent();
Button button1 = new Button();
button1.Location = new Point(100, 100);
button1.Size = new Size(187, 67);
button1.Text = "button1";
button1.Click += button1_Click;
Controls.Add(button1);
timer1 = new Timer();
timer1.Tick += timer1_Tick;
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
lock (lockObj)
{
MessageBox.Show("Entered the lock!");
MessageBox.Show("Exiting the lock...");
}
}
}
}
System.Windows.Forms.Timer dispatches its events via a windows message loop.
MessageBox.Show shows a messagebox and then pumps the windows message loop as a nested loop. This can include dispatching more events for a timer.
Since only a single thread (the UI thread) is involved, and lock is reentrant, that's why you get multiple message boxes shown.
I am a new user and i wish to add a timer to hold down the program for an hour and then continues.
This is the procedure:
Issue a command through serialport e.g. high
Holds for an hour
Issue again the same command 'high'
Holds for an hour
It repeats until a button is pressed.
How should i implement the timer? Because i tried searching online and found some examples.
I included this in Form1.cs:
static System.Timers.Timer Timer1;
void button1_Click(object sender, EventArgs e)
{
Timer1 = new System.Timers.Timer(60*60*1000);
Timer1.Elapsed += new ElapsedEventHandler(TimedEvent);
Timer1.Enabled = true;
}
private void TimedEvent(Object source, ElapsedEventArgs e)
{
serialPort1.Write("high");
}
Even though this code helps to repeat the high every hour but it only does the TimedEvent after 60 minutes. I need to write into the serialport first then execute the timer. How do i amend the codes to achieve the result i want?
Edited:
I realised that this code does not work as in the timer did not hold for an hour. Instead place it in form1_load to work.
private void Form1_Load(object sender, EventArgs e)
{
Timer1 = new System.Timers.Timer(10*1000);
Timer1.Elapsed += TimedEvent;
}
Tried this (below) but the timer didn't work
static System.Windows.Forms.Timer timer4 = new System.Windows.Forms.Timer();
void button1_Click(object sender, EventArgs e)
{
Writetoserialport();
timer4.Interval = 10000; // testing on 10second interval
timer4.Enabled = true;
}
When i remove Writetoserialport() , the program runs forever.
Call TimedEvent directly for the first run:
private void Form1_Load(object sender, EventArgs e)
{
Timer1 = new System.Timers.Timer(10*1000);
Timer1.Elapsed += TimedEvent;
TimedEvent();
}
But for something that happens as rare as hourly, a Windows Service might be a better option.
This will work but will probably crash when you close the program sometimes because System.Timers.Timer triggers the TimedEvent on a ThreadPool thread. What will probably happen sometimes is when your program is closed, the SerialPort object will be disposed, but since the Timer is still executing on on another thread it will trigger the TimedEvent and try and write to the serialPort but it will crash the program because it will have been disposed.
You should look at System.Windows.Forms.Timer which is meant for using with GUI threads like this.
// INSTEAD, TRY THIS.
// It's really late here forgot to change some code after copy pasting from
above, should be good now.
static System.Windows.Forms.Timer timer1;
void button1_Click(object sender, EventArgs e)
{
timer1 = new System.Windows.Forms.Timer(60*60*1000);
timer1.Tick += Timer1_Tick;
timer1.Enabled = true;
WriteToSerialPort(); // Call method directly for writing to port.
}
private void timer1_Tick(object sender, EventArgs e)
{
WriteToSerialPort();
}
private void WriteToSerialPort()
{
serialPort1.Write("high"); // write to port
}
Here is another example that allows you to not have a dedicated method for writing to the serial port. I would want the dedicated method so the serial port could be written to outside of the timer tick event without having to write the serial port code more than once. The code below needs to be in try...catch blocks. Note: System.Windows.Forms.Timer here.
using System;
using System.Drawing;
using System.IO.Ports;
using System.Windows.Forms;
namespace SerialPortSample
{
public partial class Form1 : Form
{
private Timer timer1 = new Timer { Interval = 1000, Enabled = false }; // initialize timer, with a one second interval and disabled
private Button startTimerButton = new Button { Name = "startTimerButton",Text = #"Toggle Timer", Size = new Size(130, 33), Location = new Point(0, 0) };
// This is a place holder for the SerialPort control you probably have on your Form.
//Remove this instance of serialPort1 and use the serialPort1 control from your form.
private SerialPort serialPort1 = new SerialPort();
public Form1()
{
InitializeComponent();
// add button to Form
this.Controls.Add(startTimerButton); // add button to form1
startTimerButton.Click += StartTimerButton_Click;
timer1.Tick += Timer1_Tick; // attach timer tick event
}
private void StartTimerButton_Click(object sender, EventArgs e)
{
timer1.Enabled = !timer1.Enabled; // toggle timer.endabled, if false the Tick event will not be raised
timer1.Interval = 1000; // set timer interval to 1000 so the next time it is enabled it triggers immediately.
}
private void Timer1_Tick(object sender, EventArgs e)
{
timer1.Interval = 60 * 60 * 1000; // set timer interval to 1 hour so it will not trigger for an hour
if (!serialPort1.IsOpen)
serialPort1.Open(); // open serial port if not open
serialPort1.Write("high"); // write to the serial port
serialPort1.Close(); // close serial port
}
}
}
I am new to C#, and I have searched I but didn't find a simple solution to my problem.
I am creating a Windows form application.
After the start button is clicked, it counts every millisecond and when it reaches specific values from an array changes a label.
How can milliseconds be counted?
-------------------------
AlekZanDer Code:
namespace timer_simple3
{
public partial class Form1 : Form
{
long result = 0;
public Form1()
{
InitializeComponent();
this.timer1 = new System.Windows.Forms.Timer(this.components);
}
private void Form1_Load(object sender, EventArgs e)
{
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
}
private void timer1_Tick(object sender, EventArgs e)
{
result = result + 1;
label1.Text = Convert.ToString(result);
}
private void btstart_Click(object sender, EventArgs e)
{
timer1.Interval = 1; //you can also set this in the
//properties tab
timer1.Enabled = true;
timer1.Start();
// label1.Text = Convert.ToString(timer1);
}
private void btstop_Click(object sender, EventArgs e)
{
timer1.Stop();
}
}
}
How can milliseconds be counted?
You can't do that, because Windows Forms Timer component is single-threaded, and is limited to an accuracy of 55 milliseconds. If you require a multithreaded timer with greater accuracy, use the Timer class in the System.Timers namespace.
Also any other timer will not give you accuracy more than 16 milliseconds (actually 15.625 milliseconds, or 64Hz). So, you can't increment some counter to count elapsed milliseconds.
Option for you - instead of long result counter use difference between current time and time of timer start:
label1.Text = (DateTime.Now - startDateTime).Milliseconds.ToString();
First you have to create a method that tells the timer what to do every [put the needed number here] milliseconds.
private void randomTimer_Tick(object sender, EventArgs e)
{
if (conditions)
{
... //stuff to do
... //more stuff to do
... //even more stuff to do
}
}
Then you set the timer to call this method: you can do this by using the events tab of the properties of the timer or write:
this.randomTimer1.Tick += new System.EventHandler(this.randomTimer1_Tick);
in the ProjectName.Designer.cs file in the private void InitializeComponent(){} method after the line this.randomTimer = new System.Windows.Forms.Timer(this.components);.
And lastly you enable the timer:
private void startButton (object sender, EventArgs e)
{
randomTimer.Interval = timeInMilliseconds; //you can also set this in the
//properties tab
randomTimer.Enabled = true;
}
Of course, you will have to set the button to call this method too.
If you don't know where the Properties window is (I assume that you are using Visual C#): it's usually a tab located on the right side of the window. In order something to appear in the tab, you have to select the form you want to edit in the design view. If there is no such tab anywhere in the window of the compiler, go to "View" -> "Other Windows" and select "Properties Window".
If the answers you have found are long and complicated, that's mostly because they are explaining the whole process with details and examples. If you use the "drag and drop" option of Visual C#, the declaration code of the forms will happen automatically, afterwards it's up to you to write the code of the methods. There are also other features that are self explanatory and make programming more pleasant. Use them!
I have two forms:
MainForm
SettingsForm
As you can imagine, MainForm uses values such as Properties.Settings.Default.Path and SettingsForm should be able to configure such a value on runtime.
But somehow SettingsForm: Properties.Settings.Default.Save(); takes effect just after application restart, although I'm reloading those settings in MainForm: Properties.Settings.Default.Reload();
I have this so far:
In MainForm.cs:
// Handles "config button click" => display settings form
private void configStatusLabel_Click(object sender, EventArgs e)
{
SettingsForm form = new SettingsForm();
form.FormClosed += new FormClosedEventHandler(form_FormClosed);
form.Show();
}
// Callback triggered on Settings form closing
void form_FormClosed(object sender, FormClosedEventArgs e)
{
Properties.Settings.Default.Reload();
}
// There are another methods called after form_FormClosed is triggered, for example
// StremWriter = new StreamWriter( Properties.Settings.Default.Path)
And SettingsForm.cs:
// Triggered on "Save button click" in Settings form, after changing values
// Example: Properties.Settings.Default.Path = "C:\\file.txt"
private void saveButton_Click(object sender, EventArgs e)
{
Properties.Settings.Default.Save();
Close();
}
What am I missing? How can I achieve "on demand change"?
More on program flow
In main form, there are several buttons which will trigger function such as ReloadLog() which uses Properties.Settings.Default.Path. So at the end I'm having functions executed at this order:
ReloadLog(); // Triggered by the user (several times)
// This reloads contents of log, say C:\\main.log
configStatusLabel_Click(); // User hit "configure button", there are two active forms
// SettingsForm is now displayed too
// At this point ReloadLog() may be called in MainForm many times
// Meanwhile in SettingsForm:
Properties.Settings.Default.Path = PathTextBox.Text;
private void saveButton_Click(object sender, EventArgs e) // User hit save button
{
Properties.Settings.Default.Save();
Close(); // This will trigger form_FormClosed in main form
}
// Now you would expect that following line will open D:\\another.log
ReloadLog();
// But it still uses original config, however when I turn app off and on again, it works
private void configStatusLabel_Click(object sender, EventArgs e)
{
SettingsForm form = new SettingsForm();
form.FormClosed += new FormClosedEventHandler(form_FormClosed);
form.FormClosed += (s, e) => { MethodThatAppliesTheSettings(); };
form.Show();
}
Currently I'm moving from java to c# and I'm full of crazy questions.
I'm trying new things on a windows form application and now,I would like to create a loop wich is executing a code every 1 minute,the problem is that I have no idea where to put this code.
For example,the form structure is like:
using System;
namespace Tray_Icon
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
notifyIcon1.ShowBalloonTip(5000);
}
private void notifyIcon1_BalloonTipClicked(object sender, EventArgs e)
{
label1.Text = "Baloon clicked!";
}
private void notifyIcon1_BalloonTipClosed(object sender, EventArgs e)
{
label1.Text = "baloon closed!";
}
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
}
private void option1ToolStripMenuItem_Click(object sender, EventArgs e)
{
//some code here
}
private void option2ToolStripMenuItem_Click(object sender, EventArgs e)
{
//some code here
}
private void option3ToolStripMenuItem_Click(object sender, EventArgs e)
{
label1.Text = "Option 3 clicked!";
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
option1ToolStripMenuItem_Click(this, null);
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnWrite_Click(object sender, EventArgs e)
{
//code here
}
}
}
Where should I put the loop code? :(
Thanks in advance for ANY replay!!!
Add a Timer to your form:
set its Interval property to 60000 (one minute in milliseconds) and Enabled to True:
and attach an event handler to the Timer.Tick event, e.g. by double-clicking the timer in the Forms designer:
private void timer1_Tick(object sender, EventArgs e)
{
// do something here. It will be executed every 60 seconds
}
You would have to add a timer, and set the interval to 1000 miliseconds, and in the OnTick event you add the code with your loop
Timer tmr = null;
private void StartTimer()
{
tmr = new Timer();
tmr.Interval = 1000;
tmr.Tick += new EventHandler<EventArgs>(tmr_Tick);
tmr.Enabled = true;
}
void tmr_Tick(object sender, EventArgs e)
{
// Code with your loop here
}
You can't put any loop code in here.
In your designer look for the Timer control. When you have that, configure it to run every minute and place your code in the Timer_Tick event.
Or create a timer manually in code and respond to the event :) But for starters, doing it by the designer is easier!
Drag a Timer component on the Form and doubleclick it. There you go with the code.
The Timer component runs in the main thread so you can modify UI components without worrying.
Alternatively You could create a System.Timers.Timer, which has it's own thread and has some advantages, but possible caveats when modifying UI components. See http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Try to use Background Worker and put the code in the backgroundWorker.DoWork or use a Timer
Use System.Timers.Timer:
System.Timers.Timer aTimer;
{
aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 60000;
aTimer.Enabled = true;
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
for using Timer see this tutorial: C# Timer
How you do it in Java platform?
I think Java should be the same with .net.
In fact, a form program is just normal program which contains a event dispatcher. The event dispatcher listen to the UI events and dispatch them to the event handlers. I think all the UI mode should like this, no matter Java or .net platform.
So generally speaking, you have 2 options:
Start the loop at beginning. In this case, you should insert your
code in the constructor of the Form.
Start the loop when user
click the button. In this case, you should insert your code in the
event handler function.
Yes, as others mentioned, you should use the timer. But this should after you know where your code should locate. You also can use a endless loop with a sleep call. But timer is a better solution.
Idea of timer is more better. But If you want to use threads. Then Follow this
Let me assume that You want to do it right from the start of program
You can write in body of function (event in fact) named Form1_Load as
Your actual code is just within while loop other code only to guide
I can guide if you don't know the use of threads in C#
bool button2Clicked = false;
private void Form1_Load(object sender, EventArgs e)
{
// A good Way to call Thread
System.Threading.Thread t1 = new System.Threading.Thread(delegate()
{
while (!button2Clicked)
{
// Do Any Stuff;
System.Threading.Thread.Sleep(60000); //60000 Millieconds=1M
}
});
t1.IsBackground = true; // With above statement Thread Will automatically
// be Aborted on Application Exit
t1.Start();
}