Window Wrokspace Dispose Control, why?

Topics: CAB & Smart Client Software Factory
Nov 28, 2006 at 12:16 PM
originally posted by: JKraft4PIT

I am currently trying to show a modal control and have a result sent back (yes make change, no cancel). That is fine I have a feeling how I am going to finish doing it.

The problem I found is when i dispose of the control from within control. ie...

//Code in my control when a buttong is pressed, a close button
this.dispose();

I don't see a problem with doing it that way since Window workspace wires up the controls dispose event.
smartPart.Disposed += ControlDisposed; //adding event
smartPart.Disposed -= ControlDisposed; //removing event

But what bothers me is why they did this.
// WindowWorkspace.cs line 113 - 122
private void ControlDisposed(object sender, EventArgs e)
{
Control control = sender as Control;
if (control != null && base.SmartParts.Contains(sender))
{
CloseInternal(control);
//this.windowDictionarycontrol.Close();
//this.windowDictionary.Remove(control);
}
}

Why are those two line commented out? Why wouldn't you want to remove the disposed part from the dictionary?

If there is any answer to this I would like to know.

Jordon

P.S. I see that "WindowFormClosed removes the entry but this doesn't get called when you dispose the control
Dec 7, 2006 at 5:30 AM
originally posted by: mklapp

I do not really know why, but if I did it, it would be because either

1. I believed that it was cheaper to keep control residue in the dictionary in case it was regenned.

2. Something is not working right and not removing the control made the problem go away.

Michael
Dec 7, 2006 at 6:59 AM
originally posted by: JKraft4PIT

I think I found the reason. When a form is added it wires up events on the form (like dispose).

The code was just moved inside these events. So when the form is disposing, it also removes it from the dictionary.

I guess I should have updated my post.

Jordon
Jan 4, 2007 at 3:27 PM
originally posted by: AlexeyNayda

Or it's even better to make it this way:
private void RemoveEntry(Conrtol spcontrol)
{
smartPart.Disposed -= ControlDisposed;

// Remove the smartPart from the form to avoid disposing it.
windowDictionarysmartPart.Controls.Remove(smartPart);
windowDictionary.Remove(smartPart);
}

and change OnClose method to:
protected override void OnClose(Control smartPart)
{
Form form = windowDictionarysmartPart;
RemoveEntry(smartPart);
form.Close();
}
Jan 4, 2007 at 3:44 PM
originally posted by: AlexeyNayda

I suppose, that the reason of why ControlDisposed() method were added is that after smartPart is disposed manually the form which hold that control should be closed too.
But current implementation caused a bug. OnClose method called only after the CloseInternal() method is called. There is only one place where CloseInteral could be executed and it's a ControlDisposed method. It means the if we want access OnClose method, first of all we need to dispose our control. It ok if we disposing the smartPart manualy, but if we are trying to close the Form it will cause the following problems:
If we take a look into the OnClose() method :
...
// Remove the smartPart from the form to avoid disposing it.
form.Controls.Remove(smartPart);
...
i can suppose that the smartPart control shouldn't be disposed if user closes the form container. So the time we will call method OnShow(..) we won't see anything on the form because of the control will be already disposed.

I propose to do the following:
we need replace
private void RemoveEntry(Control spcontrol)
{
this.windowDictionary.Remove(spcontrol);
}
with
protected virtual void RemoveEntry(Control spcontrol)
{
CloseInternal(spcontrol);
}

Plus in the MdiWorkspace in OnShow method we need to call smartPart.Show() method because of after the first time form container will be closed smartPart will call Hide() method in WindowsForm->OnClosing() method and will get Visible = false.

Sorry for my bad english! :)

Regards,
Alexey