Почему возникает исключение 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();
}
}