Why is a NullReferenceException thrown when a ToolStrip button is clicked twice - openFileDialog.showDialog()?

北城余情 提交于 2019-12-10 18:57:56

问题


I created a clean WindowsFormsApplication solution, added a ToolStrip to the main form, and placed one button on it. I've added also an OpenFileDialog, so that the Click event of the ToolStripButton looks like the following:

private void toolStripButton1_Click(object sender, EventArgs e)  
{  
    openFileDialog1.ShowDialog();  
}

I didn't change any other properties or events.

The funny thing is that when I double-click the ToolStripButton (the second click must be quite fast, before the dialog opens), then cancel both dialogs (or choose a file, it doesn't really matter) and then click in the client area of main form, a NullReferenceException crashes the application (error details attached at the end of the post). Please note that the Click event is implemented while DoubleClick is not.

What's even more strange that when the OpenFileDialog is replaced by any user-implemented form, the ToolStripButton blocks from being clicked twice.

I'm using VS2008 with .NET3.5 on Windows 7 Professional (from MSDNAA) with latest updates. I didn't change many options in VS (only fontsize, workspace folder and line numbering).

Does anyone know how to solve this? It is 100% replicable on my machine, is it on others too?

One solution that I can think of is disabling the button before calling OpenFileDialog.ShowDialog() and then enabling the button back (but it's not nice). Any other ideas?

And now the promised error details:

System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="System.Windows.Forms"
StackTrace:
at System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.PeekMessage(MSG& msg, HandleRef hwnd, Int32 msgMin, Int32 msgMax, Int32 remove)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 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(Form mainForm)
at WindowsFormsApplication1.Program.Main() w C:\Users\Marchewek\Desktop\Workspaces\VisualStudio\WindowsFormsApplication1\Program.cs:line 20
at System.AppDomain._nExecuteAssembly(Assembly 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.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:


回答1:


I was able to replicate something like this on a windows 7 Machine - I don't get exception the but my form will no longer redraw. It may be that because I am not running in a debugger on the win 7 box that the exception is being swallowed.

This does not happen on my XP machine. This only happened when I used the toolStripButton and double clicked on it the first time I opened the dialog. If I opened the dialog normally and then closed it first then the double click does not open the dialog twice.

I suspect that what is happening here is similar to a race condition - where the framework developer never expected that their code could be entered twice, but that has occurred because of a new call back into the message loop. So why is this happening - looks like a bug to me.

I found one quite easy workaround that stops it from happening - enable the DoubleClickEnabled property of the toolStripButton. You don't have to implement the double click handler - it treats the double click as a single click then and it all works.

I would handle this thus:

    public Form1()
    {
        InitializeComponent();

        // This is a workaround for a framework bug
        // see blah blah
        toolStripButton1.DoubleClickEnabled = true; 

    }

Next time you upgrade frameworks you can try removing it.

Neil




回答2:


The ShowDialog method is modal. Normally after ShowDialog is called, the OpenFileDialog has the exclusive UI focus of the application until the dialog is closed.

By quickly double clicking the button you are calling ShowDialog again before the framework has had a chance to give OpenFileDialog exclusive UI focus. This has put your application into an invalid state.

Although this shouldn't be possible, clearly it is, and now it's your problem. Either subscribe to the button's Click event and disable the button after the first click; or remove the OpenFileDialog from the Designer and create it programatically in your Click handler. If you do the latter, wrap it in a using block to ensure garbage collection:

private void toolStripButton1_Click(object sender, EventArgs e)   
{
    using(var OFD = new OpenFileDialog())
    {
        OFD.ShowDialog();  
    } 
} 



回答3:


Screen Resolution can be one of the reason that cause error in the framework. In my case i changed my screen resolution and the issue was not produced in that resolution and when ever I shift back to recomended resolution, I got the issue.



来源:https://stackoverflow.com/questions/4576775/why-is-a-nullreferenceexception-thrown-when-a-toolstrip-button-is-clicked-twice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!