Where to hook/unhook events with Forms/Controls

J

JS

I have an application with many user controls and forms which display
measurements in whatever the current unit system is. The current unit
system is kept in my 'Units' static class as Units.CurrentSystem. I
also have an event in the Units class called
Units.CurrentSystemChanged. My controls hook into this event (usually
in their OnLoad() method). However, I am not quite sure where to
unhook the event. I could do it in Dispose(), OnHandleDestroyed() or
somewhere else. I'd like to establish a pattern for doing this type
of thing in my application so if anyone has a comment I would
appreciate hearing it.
 
B

Bruce Wood

I have an application with many user controls and forms which display
measurements in whatever the current unit system is. The current unit
system is kept in my 'Units' static class as Units.CurrentSystem. I
also have an event in the Units class called
Units.CurrentSystemChanged. My controls hook into this event (usually
in their OnLoad() method). However, I am not quite sure where to
unhook the event. I could do it in Dispose(), OnHandleDestroyed() or
somewhere else. I'd like to establish a pattern for doing this type
of thing in my application so if anyone has a comment I would
appreciate hearing it.

You have two choices.

1. The low-tech solution is to un-subscribe from the even in the
Form's Dispose method. As all Forms run with .Show() are Disposed when
the user closes them, and all code that uses .ShowDialog() is supposed
to Dispose the form afterward, this will work.

2. The high-tech solution is to subscribe to the event via a weak
reference delegate. You have to build this yourself (unfortunately),
but it allows your form to subscribe to the event and say, in effect,
"This subscription doesn't count where garbage collection is
concerned."

In your case, door #1 is probably the best. However, if you find your
forms subscribing to more and more static events (as I did) then the
second option becomes the simpler of the two.
 
J

JS

Thanks for the answer. I've searched your 'high-tech' suggestion of
weak references, but I still would like to try to do this in the 'low
tech' way, partly because I'm setting the pattern for future
developers and I'd like to keep the pattern simple, and also because I
don't fully understand the implications of the weak reference scheme
yet.

I am testing with a Form right now and am currently unhooking the
event in the Dispose() method. However, I notice that when the X
(close) button is pressed with the mouse, Dispose() is not called --
at least with ShowDialog(). It is called if I call Close() in my
code. That was not what I expected, and I will need to find the right
way to do this. Still, for forms, it looks like I can use OnLoad and
OnClosed, however I'm not sure what to do yet for controls.

For controls I was considering using OnHandleDestroyed, although I'm
concerned that this may be too late -- I would prefer that whenever my
user control gets the event, it can assume that its control and child
controls are created and all normal methods and properties (Text,
Invalidate() for example) will work. So, specifically for controls,
do you have any suggestions about when to hook/unhook events in the
'low-tech' way?

Thanks.
 
J

JS

Correction, Dispose() is not called when I call Close() in the code,
at least not right away. I suspect that Close(), as well as clicking
the close box, eventually lead to a Dispose() call.
 
B

Bruce Wood

Thanks for the answer. I've searched your 'high-tech' suggestion of
weak references, but I still would like to try to do this in the 'low
tech' way, partly because I'm setting the pattern for future
developers and I'd like to keep the pattern simple, and also because I
don't fully understand the implications of the weak reference scheme
yet.

I am testing with a Form right now and am currently unhooking the
event in the Dispose() method. However, I notice that when the X
(close) button is pressed with the mouse, Dispose() is not called --
at least with ShowDialog().

If you use ShowDialog then you must always call Dispose() on the form
after you're finished with it. That is, the function that creates the
dialog and shows it must also dispose of it. The easiest way to do
this is via the using statement:

using (MyDialog dlg = new MyDialog())
{
DialogResult result = dlg.ShowDialog();
if (result == DialogResult.OK)
{
... get information from dlg and do something with it ...
}
}

dlg.Dispose() is automatically called when control leaves the using
statement.

If, on the other hand, you show your form using .Show(), Windows
should automatically call Dispose() on it when the user closes it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top