Почему возникает исключение NullReferenceException при двойном нажатии кнопки ToolStrip - openFileDialog.showDialog()?

Я создал чистое решение для WindowsFormsApplication, добавил ToolStrip к основной форме, и поместил одну кнопку на нем. Я добавил также OpenFileDialog, таким образом Click событие ToolStripButton выглядит следующим образом:

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

Я не изменил никаких других свойств или событий.

Самое смешное, что когда я дважды щелкаю ToolStripButton (второй щелчок должен быть достаточно быстрым, прежде чем откроется диалоговое окно), затем отмените оба диалоговых окна (или выберите файл, это не имеет большого значения), а затем щелкните в клиентской области главной формы, NullReferenceException вылетает приложение (подробности об ошибках прикреплены в конце поста). Обратите внимание, что Click событие реализуется пока DoubleClick нет

Что еще более странно, что когда OpenFileDialog заменяется любой реализованной пользователем формой, ToolStripButton блоки от нажатия дважды.

Я использую VS2008 с.NET3.5 на Windows 7 Professional (от MSDNAA) с последними обновлениями. Я не изменил много параметров в VS (только размер шрифта, папка рабочего пространства и нумерация строк).

Кто-нибудь знает как это решить? Это 100% тиражируется на моей машине, на других тоже?

Одно из решений, которое я могу придумать, - отключение кнопки перед вызовом. OpenFileDialog.ShowDialog() и затем включение кнопки назад (но это не приятно). Есть другие идеи?

А теперь обещанные детали ошибки:

System.NullReferenceException не было обработано
Message="Ссылка на объект не установлена ​​на экземпляр объекта."
Источник ="System.Windows.Forms"
Трассировки стека:
в System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
в System.Windows.Forms.UnsafeNativeMethods.PeekMessage(MSG& msg, HandleRef hwnd, Int32 msgMin, Int32 msgMax, Int32 удалить)
в System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, причина Int32, Int32 pvLoopData)
в System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(причина Int32, контекст ApplicationContext)
в System.Windows.Forms.Application.ThreadContext.RunMessageLoop(причина Int32, контекст ApplicationContext)
в System.Windows.Forms.Application.Run(Форма mainForm)
в WindowsFormsApplication1.Program.Main() w C:\Users\Marchewek\Desktop\Workspaces\VisualStudio\WindowsFormsApplication1\Program.cs: строка 20
в System.AppDomain._nExecuteAssembly(сборка сборки, аргументы String[])
в System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
в System.Threading.ThreadHelper.ThreadStart_Context(состояние объекта)
в System.Threading.ExecutionContext.Run(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта)
в System.Threading.ThreadHelper.ThreadStart ()
InnerException:

3 ответа

Мне удалось воспроизвести что-то подобное на Windows 7 Machine - я не получаю исключения, но моя форма больше не будет перерисовываться. Возможно, из-за того, что я не работаю в отладчике на коробке с win 7, исключение проглатывается.

Это не происходит на моей машине XP. Это произошло только тогда, когда я использовал toolStripButton и дважды щелкнул по нему при первом открытии диалога. Если я нормально открыл диалоговое окно, а затем сначала закрыл его, то двойной щелчок не открывает диалоговое окно дважды.

Я подозреваю, что то, что происходит здесь, похоже на состояние гонки - когда разработчик фреймворка никогда не ожидал, что их код может быть введен дважды, но это произошло из-за нового вызова обратно в цикл сообщений. Так почему это происходит - похоже на ошибку для меня.

Я нашел один довольно простой обходной путь, который останавливает его - включите свойство DoubleClickEnabled toolStripButton. Вам не нужно реализовывать обработчик двойного щелчка - он обрабатывает двойной щелчок как один щелчок, и все работает.

Я бы справился с этим так:

    public Form1()
    {
        InitializeComponent();

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

    }

При следующем обновлении фреймворков вы можете попытаться удалить его.

Нил

Разрешение экрана может быть одной из причин, вызывающих ошибку в рамках. В моем случае я изменил разрешение экрана, и проблема не возникла в этом разрешении, и когда я возвращался к рекомендованному разрешению, я получал проблему.

Метод ShowDialog является модальным. Обычно после вызова ShowDialog OpenFileDialog имеет эксклюзивный UI-фокус приложения, пока диалоговое окно не будет закрыто.

Быстро дважды щелкнув по кнопке, вы снова вызываете ShowDialog до того, как у фреймворка появится возможность выделить OpenFileDialog эксклюзивный пользовательский интерфейс. Это привело ваше заявление в недопустимое состояние.

Хотя это не должно быть возможным, ясно, что это так, и теперь это ваша проблема. Либо подпишитесь на событие Click кнопки и отключите кнопку после первого щелчка; или удалите OpenFileDialog из Designer и создайте его программно в вашем обработчике Click. Если вы сделаете последнее, оберните его в блок using, чтобы обеспечить сборку мусора:

private void toolStripButton1_Click(object sender, EventArgs e)   
{
    using(var OFD = new OpenFileDialog())
    {
        OFD.ShowDialog();  
    } 
} 
Другие вопросы по тегам