What event signals that a UserControl is being destroyed?

47,655

Solution 1

I suggest the Control::HandleDestroyed event. It is raised, when the underlying HWnd is destroyed (which usually happens, when the parent form is closed). To handle it in your own UserControl, you should override OnHandleDestroyed.

You have full access to the Control's properties at this moment, because it is not yet disposed of.

Solution 2

Another solution

    protected override void OnParentChanged(EventArgs e)
    {
        base.OnParentChanged(e);

        if (parentForm != null)
        {
            parentForm.Closing -= parentForm_Closing;
        }
        parentForm = FindForm();

        if (parentForm != null)
            parentForm.Closing += parentForm_Closing;
    }

    void parentForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        parentForm.Closing -= parentForm_Closing;
        parentForm = null;
        //closing code
    }

Solution 3

Why not just use the Disposed event?

When a form is closing, it will call Dispose on itself and all child controls will be disposed recursively as well.

Solution 4

Try this:

UserControl.Dispose();
Share:
47,655
Gary McGill
Author by

Gary McGill

Updated on September 15, 2020

Comments

  • Gary McGill
    Gary McGill over 3 years

    I have a UserControl-derived control the displays some information fetched from a web server. I'm currently in the process of making the initialization of the control asyncronous, to improve responsiveness.

    In my Load event handler, I'm creating a CancellationTokenSource, and using the associated Token in the various async calls.

    I now want to ensure that if the user closes the form before the async operation completes, the operation will be cancelled. In other words, I want to call Cancel on the token.

    I'm trying to figure out where to do this. If there was an Unload event that I could trap, then that would be perfect - but there isn't. In fact, I can't find any event that looks suitable.

    I could trap the close event for the containing Form, but I really wanted to keep everything local to my UserControl.

    Suggestions?

  • Stephan
    Stephan over 11 years
    Are you sure, the form will call Dispose on child controls when closing? I thought it was under the resposibililty of the calling code to dispose of a Form.
  • Gary McGill
    Gary McGill over 11 years
    Hmmm... I'm wary of Dispose, because it's never clear exactly when (and indeed whether) it will be called. If it isn't called until the GC gets involved, then that's too late for my purposes.
  • Gary McGill
    Gary McGill over 11 years
    I made a similar comment about using the Disposed even (see Mr. Steak's answer). I worry that this event may not be "early" enough, since it may in fact not happen until Dispose is called - since this is an obvious thing for Dispose to do.
  • Gary McGill
    Gary McGill over 11 years
    I'm more-or-less persuading myself that I need to do it from the point of view of the form itself, rather than keeping it local to the control...
  • Stephan
    Stephan over 11 years
    Ok, I found it. Dispose is automatically called when closing a modeless form. When displaying a modal dialog by calling Form::ShowDialog(), the calling code has to do the cleanup (or the garbage collector will do it sooner or later).
  • Gary McGill
    Gary McGill over 11 years
    Yeah, that's too many ifs and buts for my liking. I'll change tack, I think. Thanks anyway.
  • Gary McGill
    Gary McGill over 11 years
    Thanks, but I was looking for an event that I could trap that signals to me that the control is being disposed - not for a way to cause it to be disposed.
  • Julien
    Julien over 10 years
    Just be careful that this is called when the control is used in the designer. One may want to use if (!DesignMode) in the overrides body.
  • yu_sha
    yu_sha over 7 years
    This won't work if control is child of another control - when parent changes the parent form is still null. Solution is to also handle VisibleChanged event.
  • Gabriel Marius Popescu
    Gabriel Marius Popescu over 7 years
    The error in the solution above is: An object reference is required for the non-static field, method or property 'Component.Dispose()'
  • Stephan
    Stephan almost 5 years
    @Elmue: It might be the case that OnHandleDestroyed is called somehow by Dispose. But that is not the point. Dispose of an embedded control is called when Dispose of the parent is called. When someone does not dispose of a form for some reason then Dispose on the user control might be called much later. And that does not match the OP's requirements.
  • nivs1978
    nivs1978 over 2 years
    @GaryMcGill I think what Gimhan mean is that in the .Designer.cs file you have a dispose method that will be called whenever the parent form the user control is in is closed. In other words you can just ad your code that needs to be run when the UserControl is disposed into this. In case your form is not closed, but the usercontrol is removed from the form, you can call the Dispose() methid directly as Gimhan suggests.