Timer doesn't stop after closing form C# - c#

i create timer in my form, but after i close form, timer still working.
I tried different ways to stop this timer, but did not have any success.
what is problem?
private Timer timer100;
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.timer100 = new System.Windows.Forms.Timer(this.components);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed);
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
timer100.Stop();
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
timer100.Dispose();
timer100 = null;
}

I did not put InitializeComponent() in MainForm's constructor as jhmt mentioned in comments.

Related

How to pass custom EventArgs to UI controls

Unfortunately I was not able to find relevant answer to my problem. I have a object encoder that has an event "VideoEncoding". It passes custom EncodingEventArgs that include various Properties like Progress, Size etc. I can output this info to Console or write to text file. But when I try to utilize it in WinForms I'm not able to pass that information to UI like label or progress bar. I tried different approaches. Background Worker seems like a good idea, The problem is that Background Worker cannot subscribe to VideoEncoding event, neither it will take my custom EventArgs. This is what i was able to put together. Maybe there is a different way to do it using delegates that would communicate with UI. Any suggestions are welcome. Thank you.
public partial class Form1 : Form
{
private BackgroundWorker bw;
int _progress;
public Form1()
{
InitializeComponent();
this.bw = new BackgroundWorker();
this.bw.DoWork += new DoWorkEventHandler(bw_DoWork);
this.bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
this.bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
this.bw.WorkerReportsProgress = true;
this.button1.Click += new EventHandler(button1_Click);
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.label1.Text = "The job is: " + e.Result.ToString();
this.button1.Enabled = true;
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.label2.Text = e.ProgressPercentage.ToString() + "% complete";
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker)sender;
this.Encode
worker.ReportProgress(_progress);
e.Result = "Completed";
}
private void button1_Click(object sender, EventArgs e)
{
if (!this.bw.IsBusy)
{
this.bw.RunWorkerAsync();
this.button1.Enabled = false;
}
}
public void Encode()
{
var job = new EncodingJob();
//setup encoding job
//subscribe to an event
ffmpeg.VideoEncoding += GetProgress;
ffmpeg.DoWork(job);
}
public void GetProgress(object sender, EncodingEventArgs e)
{
_progress = (int)e.Progress;
}
}
Try to call the background workers ReportProgress in the GetProgress Method. How should the form know your progress if you don't signalize it?

How do you open a start form and close it after some instructions are displayed?

I have a form(f1) that needs to run some instructions before opening another one(f2), and when it ends must close. I set in program.cs Application.Run(new f1());and at the end of f1 istructions I wrote
f2 f = new f2();
f.ShowDialog();
this.Close();
but it doesn't close, just goes in background.
Everything should work the way you have it but hide f1 and display f2 this way:
this.Hide();
var frm2 = new f2();
frm2.Closed += (sender, args) => this.Close();
frm2.Show();
To give a more detailed answer:
public class Form1() : Form
{
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
var worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, DoWorkEventArgs e) {
Thread.Sleep(5000);
// this is where you can load your data from file
}
private void worker_RunWorkerCompleted(
object sender, RunWorkerCompletedEventArgs e)
{
this.Hide();
var frm2 = new Form2();
frm2.Closed += (s, a) => this.Close();
frm2.Show();
}
}
So Form1 will start to load data using a background worker. When the data is loaded, the BackgroundWorker will fire the RunWorkerCompleted event. That event handler will hide Form1 instead of closing it, create Form2, add a handler for form2's Closed event so that closing Form2 will stop your application, and then shows Form2.

I want to open a second form AFTER opening the main form, but the second form opens first

I am trying to open a secondary form immediately after the main form displays, but instead, the secondary form displays first and then the main form displays after the secondary one closes (The second form is acting like a splash screen). Here is an example:
private void Form1_Load(object sender, EventArgs e)
{
doSomething1(sender, e);
doSomething2(sender, e);
// The new form I want to open after the main form.
Form2 f2 = new Form2();
doSomething3(sender, e);
}
private void doSomething1(object sender, EventArgs e)
{
// Do something here...
}
private void doSomething2(object sender, EventArgs e)
{
// Do something here...
}
private void doSomething3(object sender, EventArgs e)
{
// Do something here...
}
Use the Form1.Shown event instead of the Load event:
private void Form1_Shown(Object sender, EventArgs e) {
doSomething1(sender, e);
doSomething2(sender, e);
// The new form I want to open after the main form.
Form2 f2 = new Form2();
doSomething3(sender, e);
}
Alternatively, depending on whether doSomething1 and doSomething2 are doing background processing that the user doesn't need to see: you could retain those two in the load handler, and merely move the last two statements into the Shown handler.
In your constructor initialized the Shown event handler first:
public Form1()
{
InitializeComponent();
this.Shown += new EventHandler(Form1_Shown);
}
Then put the code there:
void Form1_Shown(object sender, EventArgs e)
{
doSomething1(sender, e);
doSomething2(sender, e);
// The new form I want to open after the main form.
Form2 f2 = new Form2();
doSomething3(sender, e);
}
public Form1()
{
InitializeComponent();
Form2 f2 = new Form2();
f2.Show();

I need to close the previous active window when navigating a windows form with menustrip

I'm putting together a simple UI that interacts with a SQL database. My problem is a UI problem, ever time a menustrip item is selected, it opens a new active window. How do I set this up to close the previous active window? I've tried using Form.Close();, but that just closes everything.
private void addCampusToolStripMenuItem_Click(object sender, EventArgs e)
{
if_add_campus go = new if_add_campus();
go.Show();
}
private void addDepartmentToolStripMenuItem_Click(object sender, EventArgs e)
{
if_add_dept go = new if_add_dept();
go.Show();
}
private void addEmployeToolStripMenuItem_Click(object sender, EventArgs e)
{
if_add_employee go = new if_add_employee();
go.Show();
}
Just keep track of the last form you created in a variable:
private Form lastForm;
private void showForm(Form frm) {
frm.FormClosed += (sender, ea) => {
if (object.ReferenceEquals(lastForm, sender)) lastForm = null;
};
frm.Show();
if (lastForm != null) lastForm.Close();
lastForm = frm;
}
And use showForm() to display your forms:
private void addCampusToolStripMenuItem_Click(object sender, EventArgs e)
{
showForm(new if_add_campus());
}
Not tested, should be close.

How to dispose of NotifyIcon, after the timeout has occured (C#)

I have a NotifyIcon method, although I would like the timeout to happen, before disposing of the BaloonTip.
private void button1_Click(object sender, EventArgs e)
{
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(30000);
<wait until timeout occurs>
notifyIcon1.Dispose();
}
notifyIcon1.BalloonTipClosed += delegate {notifyIcon1.Dispose ();};
I would rather hide the NotifyIcon instead of recreating/disposing a new instance of it.
Try using a timer.
Should be something like...:
private Timer taskTimer;
private NotifyIcon notifyIcon1;
private void button1_Click(object sender, EventArgs e)
{
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(30000);
taskTimer = new Timer(TimerCallback, notifyIcon1, 30000, System.Threading.Timeout.Infinite);
}
and...
void TimerCallback(object notifyIcon1Obj)
{
lock (notifyIcon1Obj)
{
NotifyIcon notifyIcon1 = (NotifyIcon)notifyIcon1Obj;
notifyIcon1.dispose();
notifyIcon1 = null;
}
}
HTH

Categories