在WinForms应用程序中将按钮样式设置为FlatStyle.System时发生System.ObjectDispos
本文关键字:System FlatStyle ObjectDispos 设置 应用程序 WinForms 样式 按钮 | 更新日期: 2023-09-27 18:24:26
System.ObjectDisposedException
当WinForms应用程序中的按钮样式设置为FlatStyle.System
时
我有一个子窗体,它在单击父窗体中的按钮时显示。代码如下所示。
Public Class Parent
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub btnOpenChild_Click(sender As Object, e As EventArgs) Handles btnOpenChild.Click
Child.Show()
End Sub
End Class
子窗体又有一个关闭自身的按钮。
Public Class Child
Private Sub btnCloseMe_Click(sender As Object, e As EventArgs) Handles btnCloseMe.Click
Me.Close()
End Sub
End Class
获取异常的步骤:
- 在调试模式下,在
Me.Close()
上设置一个断点 - 然后单击子项的关闭按钮
- 点击断点打开记事本
- 回到解决方案,然后继续
例外:
System.ObjectDisposedException was unhandled
HResult=-2146232798
Message=Cannot access a disposed object.
Object name: 'Button'.
Source=System.Windows.Forms
ObjectName=Button
StackTrace:
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.PointToScreen(Point p)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(ApplicationContext context)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at WindowsApplication2.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
有人知道吗,当按钮样式设置为FlatStyle.System
很快,它就变成了一个bug。Button
/ButtonBase
内部实现维护一些与鼠标状态相关的标志,在这种情况下这些标志没有被正确清除。FlatStyle.System
似乎是一个特殊情况,涉及源代码中的许多分支,因此显然其中一些分支缺少了一些内容。
解决方法是创建并使用您自己的Button
子类,如下所示(对不起C#,我相信您可以将其转换为VB):
public class MyButton : Button
{
protected override void OnMouseUp(MouseEventArgs mevent)
{
if (this.IsDisposed) return;
base.OnMouseUp(mevent);
}
}