3

I have a very simple custom UserControl, named MyControl

In my form I have this code (I tried to put it into LoadEvent and constructor, after InitalizeCompoment):

var crl = new MyControl();
Controls.Add(ctrl);
ctrl.HandleDestroyed+=(sender,evt) => { MessageBox.Show("Destroyed") };

But when I close the form handler is never called.

redcalx
  • 8,177
  • 4
  • 56
  • 105
stefano m
  • 4,094
  • 5
  • 28
  • 27
  • possible duplicate of [How to know when a UserControl is no longer used (no Close event)](http://stackoverflow.com/questions/7256021/how-to-know-when-a-usercontrol-is-no-longer-used-no-close-event) – Ian Goldby Jul 30 '15 at 13:52

2 Answers2

5

If it's on the main form, then I don't think the event gets called. Try disposing the control in the FormClosing event in order to force the event to be called:

void Form1_FormClosing(object sender, FormClosingEventArgs e) {
  crl.Dispose();
}

Another way is to add the FormClosing event to the UserControl:

void UserControl1_Load(object sender, EventArgs e) {
  this.ParentForm.FormClosing += new FormClosingEventHandler(ParentForm_FormClosing);
}

void ParentForm_FormClosing(object sender, FormClosingEventArgs e) {
  OnHandleDestroyed(new EventArgs());
}

or in Lambda methodology:

void UserControl1_Load(object sender, EventArgs e) {
  this.ParentForm.FormClosing += (s, evt) => { OnHandleDestroyed(new EventArgs()); };
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • wow.. it's resolved my problem, now i understood that i should dispose childs explicit, not by calling base.dispose().. thanks a lot! – stefano m Dec 28 '11 at 16:25
2

The HandleDestroyed event is called if the closing form is not the main form. If the main form is closed, then the application gets aborted and the events do not fire any more.

I made a test by starting the application like this:

Form1 frmMain = new Form1();
frmMain.Show();
Application.Run();

Now closing the main form does not cancel the application any more. In the form I do this:

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    new Thread(() =>
    {
        Thread.Sleep(5000); // Give enough time to see the message boxes.
        Application.Exit();
    }).Start();
}

And now the HandleDestroyed and Disposed events get called on the control.

public Form1()
{
    InitializeComponent();
    button4.HandleDestroyed += new EventHandler(button4_HandleDestroyed);
    button4.Disposed += new EventHandler(button4_Disposed);
}

void button4_Disposed(object sender, EventArgs e)
{
    MessageBox.Show("Disposed");
}

void button4_HandleDestroyed(object sender, EventArgs e)
{
    MessageBox.Show("HandleDestroyed");
}
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188