C# WinForms应用程序中按钮样式设置为FlatStyle.System时System.ObjectDisposedException

C# WinForms应用程序中按钮样式设置为FlatStyle.System时System.ObjectDisposedException,c#,vb.net,winforms,exception,button,C#,Vb.net,Winforms,Exception,Button,当WinForms应用程序中的按钮样式设置为FlatStyle.System时,System.ObjectDisposedException 我有一个子窗体,它会在单击父窗体中的按钮时显示。代码如下所示 Public Class Parent Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load End Sub Private Sub btnOpenChild_Clic

当WinForms应用程序中的按钮样式设置为FlatStyle.System时,
System.ObjectDisposedException

我有一个子窗体,它会在单击父窗体中的按钮时显示。代码如下所示

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。
按钮
/
按钮库
内部实现维护一些与鼠标状态相关的标志,在这种情况下,这些标志没有正确清除
FlatStyle.System
似乎是一个特例,涉及到源代码中的许多分支,因此显然其中一些分支缺少某些内容

解决方法是创建并使用您自己的
按钮
子类,如下所示(对不起C#,我相信您可以将其转换为VB):


这是在您的应用程序中引起问题还是只是好奇?在我的实时应用程序中,单击“关闭”按钮时,有一个长时间运行的过程,至少持续10到15秒。同时,如果用户单击任何其他应用程序,如记事本、word文档或chrome,则会弹出此错误。调试UI有造成此类问题的诀窍。调试器中断本身可以使事件以不同的方式触发,它可以导致聚焦和绘制事件。在这种情况下,激活另一个进程就是触发器。我假设它与捕获属性有关,这对按钮至关重要。在极端情况下,可能需要使用远程调试器,以便调试器本身不会影响UI。这不是一个极端的情况,简单地说,不启动记事本是一个解决办法。继续开车。
public class MyButton : Button
{
    protected override void OnMouseUp(MouseEventArgs mevent)
    {
        if (this.IsDisposed) return;
        base.OnMouseUp(mevent);
    }
}