vineri, 6 noiembrie 2009

[C#] ObjectDisposedException / ToolStripButton

I see many times this exception reported by QA:

exception:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'PopupContainerForm'.
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Form.CreateHandle()
at DevExpress.XtraEditors.XtraForm.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.ToolTip.get_CreateParams()
at System.Windows.Forms.ToolTip.CreateHandle()
at System.Windows.Forms.ToolTip.Hide(IWin32Window win)
at System.Windows.Forms.ToolStrip.UpdateToolTip(ToolStripItem item)
at System.Windows.Forms.ToolStripItem.OnMouseHover(EventArgs e)
at System.Windows.Forms.ToolStripControlHost.HandleMouseHover(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnMouseHover(EventArgs e)
at System.Windows.Forms.Control.WmMouseHover(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ComboBox.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

First I have suspected to be a DevExpress issue. But searching on their support site I have found the following link:
http://devexpress.com/Support/Center/p/DB11990.aspx?searchtext=System.ObjectDisposedException&p=T4|P0|0

They offer a solution that does not contain any DevExpress comtrol. They say that with that application it can be easily reproduced the problem. I can not.

So, DevExpress team declines their responsibility for this problem and put this exception on the arms of using ToolStrip buttons.

Dig in I have found another article about System.ObjectDisposedException and ToolStrip:
http://www.actiprosoftware.com/support/forums/viewforumtopic.aspx?forumtopicid=1665
Here I found out some affirmation that I can confirm:

-- "It seems like they initialize their internal tooltip to the first parent window that is there when a tooltip is displayed. However if the parent window changes, the ToolStrip never updates the internal tooltip to tell it that the parent window has changed. In your case the first parent window is disposed, thus causing the error. " - in my code the parent control is changing.

-- "ToolTip t = (ToolTip)toolStrip1.GetType().GetProperty("ToolTip", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(toolStrip1, null);
t.RemoveAll();" - use this code to remove all tooltips from ToolStripButton as a workaround

The method of System.Windows.Forms.Control.CreateHandle() looks like:

[EditorBrowsable(EditorBrowsableState.Advanced), UIPermission(SecurityAction.InheritanceDemand, Window=UIPermissionWindow.AllWindows)]
protected virtual void CreateHandle()
{
IntPtr zero = IntPtr.Zero;
if (this.GetState(0x800))
{
throw new ObjectDisposedException(base.GetType().Name);
}

.....
}

where this in this case is TopLevelControl control:


protected virtual CreateParams CreateParams
{
[SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode), SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
get
{
CreateParams params = new CreateParams();
if (this.TopLevelControl != null)
{
params.Parent = this.TopLevelControl.Handle;
}
}
....
}

So, the variant with changing the TopLevelControl could be true.


Niciun comentariu:

Trimiteți un comentariu