By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,956 Members | 1,683 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,956 IT Pros & Developers. It's quick & easy.

Invalidated Event On Form Close

P: 12
I have an application that uses multiple forms with one form constantly open. I need to be able to refresh a control of the main form when one of the other forms closes. Is there a way to generate an Invalidated event on a control in the main form when I close the other?
Jan 13 '09 #1
Share this Question
Share on Google+
7 Replies


vinci
P: 62
You need to have a custom event handler.
Your Main form listens to the custom event when it is triggered from your other forms, in your case maybe in the closing event of the form...
So whenever the form closes, the event is fired where the control in your main form gets refreshed...

If you don't get what i mean, try reading C# Snippet Tutorial - Custom Event Handlers | Switch on the Code

Cheers
Jan 13 '09 #2

P: 12
Thank you Vinci,

I found that during a google search for this, but I think it's a bit more complicated than I need. All I need is a simple way to let the main form know that it needs to redraw a listbox when the other form closes ( or when the OK button the the other form is clicked.)

Is there no way of doing this without creating a complete new class?
Jan 13 '09 #3

vekipeki
Expert 100+
P: 229
Actually it is not that complicated. Just attach a handler to the FormClosing event for each child form that you create, and then update your list in the handler.

Do this for each child form you create:
Expand|Select|Wrap|Line Numbers
  1. // create your child form
  2. ChildForm childForm = new ChildForm();
  3.  
  4. // attach the event handler to the FormClosing event
  5. childForm.FormClosing += new FormClosingEventHandler(childForm_FormClosing);
  6.  
Add code to handle the event when your child form is being closed:
Expand|Select|Wrap|Line Numbers
  1. /// <summary>
  2. /// Handles the FormClosing event of the sender control.
  3. /// </summary>
  4. /// <param name="sender">The source of the event.</param>
  5. /// <param name="e">The <see cref="System.Windows.Forms.FormClosingEventArgs"/> instance containing the event data.</param>
  6. private void childForm_FormClosing(object sender, FormClosingEventArgs e)
  7. {
  8.      // detach the event handler
  9.      Form form = (Form)sender;
  10.      form.FormClosing -= new FormClosingEventHandler(childForm_FormClosing);
  11.  
  12.      // update your list here
  13.      // ...
  14. }
Jan 13 '09 #4

P: 12
Sorry vekipeki, I don't understand what you're trying to tell me.

After further thought, I like the idea of a new class. That way I can update the ListBox whenever I need without closing the form. Looking at what vinci gave me, I created a small two form app to give it a try. Here's what I have:

Form1:
Expand|Select|Wrap|Line Numbers
  1. namespace EventTest
  2. {
  3.     public partial class Form1 : Form
  4.     {
  5.         Car car = new Car();
  6.         public Form1()
  7.         {
  8.             InitializeComponent();
  9.             car.OwnerChanged += new System.EventHandler(car_OwnerChanged);
  10.         }
  11.  
  12.         private void Form1_Load(object sender, EventArgs e)
  13.         {
  14.  
  15.         }
  16.  
  17.         private void button1_Click(object sender, EventArgs e)
  18.         {
  19.             Form2 ui = new Form2();
  20.             DialogResult dr = ui.ShowDialog();
  21.         }
  22.  
  23.         void car_OwnerChanged(object sender, EventArgs e)
  24.         {
  25.             MessageBox.Show("Form1", "Error", MessageBoxButtons.OK);
  26.  
  27.             textBox1.Text = "Well?";
  28.         }
  29.  
  30.     }
  31. }
  32.  
Form2:
Expand|Select|Wrap|Line Numbers
  1. namespace EventTest
  2. {
  3.     public partial class Form2 : Form
  4.     {
  5.         Car car = new Car();
  6.  
  7.         public Form2()
  8.         {
  9.             InitializeComponent();
  10.         }
  11.         private void Form2_Load(object sender, EventArgs e)
  12.         {
  13.         car.OwnerChanged += new EventHandler(car_OwnerChanged);
  14.  
  15.         }
  16.  
  17.         private void button1_Click(object sender, EventArgs e)
  18.         {
  19.             car.CarOwner = "The Reddest";
  20.         }
  21.  
  22.         void car_OwnerChanged(object sender, EventArgs e)
  23.         {
  24.             MessageBox.Show("Form2", "Error", MessageBoxButtons.OK);
  25.         }
  26.     }
  27. }
  28.  
When I click on Form2's button, it generates the Event in Form2 only. Nothing happens in Form1.
Jan 13 '09 #5

P: 12
I found exactly what I need here..

C# calling parent functions from child form - CodeCall Programming Forum

I just need to declare the listbox as public, and pass the form1 instance to form2 when I create it. Now in form2, I just put this in the button1_click function..

m_parent.textBox1.Text = "SWEET!!";

Whala! Works like I need it to.

vinci, I'd still like to know what's wrong with my attempt at your solution though. It may come in handy later on..

Thanks being here guys..
Jan 14 '09 #6

vekipeki
Expert 100+
P: 229
You have two different instances of your Car class, one in Form1, and one in Form2.

In Form2, you are changing Form2.car.CarOwner, so you cannot expect to have the event triggered for Form1.car. If you want to fire an event from Form2, you need to have an event there (in Form2), not in Car class, in order to write something like:

Expand|Select|Wrap|Line Numbers
  1. // create new Form2 instance
  2. Form2 form2 = new Form2();
  3.  
  4. // attach the handler for your custom event
  5. form2.SomethingHappened += new EventHandler(form2_SomethingHappened);
  6.  
  7. // show the form after attaching
  8. form2.Show();
  9.  
If you are not tight with your deadlines, try to refactor your code to use events rather than making your controls public. The whole point of making a property private is to prevent yourself from accessing it from other points in your program.

By firing an event from Form2, you show that Form2 does not care who will respond to that event, or how it will be handled, meaning that you can maybe reuse your Form2 in an application that doesn't have a Form1 class.
Jan 14 '09 #7

P: 12
Now I understand.

In order to catch an event from a child form, the event has to be attached prior to showing the child form. Also, the object triggering the event needs to be public. In this case car has to be defined as public within the child form.

This code works as should, triggering the event in both forms:

Form1:
Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Windows.Forms;
  3.  
  4. namespace EventTest
  5. {
  6.     public partial class Form1 : Form
  7.     {
  8.         public Form1()
  9.         {
  10.             InitializeComponent();
  11.         }
  12.  
  13.         private void Form1_Load(object sender, EventArgs e)
  14.         {
  15.         }
  16.  
  17.         private void button1_Click(object sender, EventArgs e)
  18.         {
  19.             Form2 form2 = new Form2();
  20.             form2.car.OwnerChanged += new EventHandler(car_OwnerChanged);
  21.             DialogResult dr = form2.ShowDialog();
  22.         }
  23.  
  24.         void car_OwnerChanged(object sender, EventArgs e)
  25.         {
  26.             MessageBox.Show("Form1", "Event", MessageBoxButtons.OK);
  27.             textBox1.Text = "Well?";
  28.         }
  29.    }
  30. }
  31.  
Form2:
Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Windows.Forms;
  3.  
  4. namespace EventTest
  5. {
  6.     public partial class Form2 : Form
  7.     {
  8.       public Car car = new Car();
  9.  
  10.         public Form2()
  11.         {
  12.             InitializeComponent();
  13.             car.OwnerChanged += new EventHandler(car_OwnerChanged);
  14.         }
  15.  
  16.         private void Form2_Load(object sender, EventArgs e)
  17.         {
  18.         }
  19.  
  20.         private void button1_Click(object sender, EventArgs e)
  21.         {
  22.             car.CarOwner = "The Reddest";
  23.         }
  24.  
  25.         void car_OwnerChanged(object sender, EventArgs e)
  26.         {
  27.             MessageBox.Show("Form2", "Event", MessageBoxButtons.OK);
  28.         }
  29.     }
  30. }
  31.  
I'm not sure of the copyright on the Car class, so I'll not post it. It was taken verbatim from the link in the second post above by vinci.

There is no real deadline for this project. I've volunteered to write a database application for the local veterans office. I've also taken this opportunity to learn C#.

I'll take your advice and use events rather than public controls. I think it will make the whole application run smoother.

Thank you for your help.
Jan 14 '09 #8

Post your reply

Sign in to post your reply or Sign up for a free account.