背景:
最初用 .NET 1.1 编写的 WinForms 应用程序通过 Visual Studio 迁移到 .NET 4.0。主应用程序窗体顶部的典型菜单栏(注意:未迁移到 ToolStripMenuItem),正如您可能期望的那样,有一个包含退出菜单项的文件菜单项。
我已经实现了 Ctrl-L 快捷方式,它会弹出一个模式锁定表单。我在主窗体上还有一个计时器组件,如果在可配置的时间段内没有活动,它会自动调出锁定窗体。
当显示锁定表单时,您可以解锁(要求用户重新登录)或退出。如果您选择退出,那么我的代码会调用 fileExitMenuItem.PerformClick()。
问题:
迁移后出于某种奇怪的原因,如果我退出自动显示或由于 Ctrl-L 快捷方式显示的锁定表单,那么我会在 fileExitMenuItem.PerformClick() 代码行上抛出 NullReferenceException。
fileExitMenuItem 不为空;打开 break-when-exception-thrown 后,我可以浏览所有 fileExitMenuItems 属性。
我可以中断表单的设计器代码并观察附加的单击事件处理程序。如果我直接使用 File >> Exit 菜单项,我可以中断事件处理程序中的代码。
所以这是一个完全的WTF时刻。任何关于看什么的建议将不胜感激
[更新 1] 这里要求的是一些代码 - 每当用户按下 Ctrl-L 或锁定计时器结束时都会调用此方法:
private void LockApplication()
{
try
{
// Stop the timer so we don't get any more elapsed events whilst we are waiting
// for a user to respond to the lockdown dialog. In addition stop the callout reminder
// time as once we have locked we don't want that doing it's thing.
lockdownTimer.Stop();
calloutsReminderTimer.Stop();
// Clone the current identity so we can check it later.
var previousIdentity = (CudosIdentity)BOUtilities.CurrentIdentity.Clone();
// Show lockdown form.
System.Windows.Forms.DialogResult result;
using (var lockForm = new Forms.applicationLockedForm())
result = lockForm.ShowDialog(this);
if (result == DialogResult.OK)
{
// Did we unlock with a different login?
if (!previousIdentity.Equals(BOUtilities.CurrentIdentity))
{
// Yes, so lose all changes.
CloseOpenForms();
if (_currentLoadSpec != null)
_currentLoadSpec.CancelContent();
}
RefreshLockTimerSetting(null);
}
else
fileExitMenuItem.PerformClick();
}
catch (Exception ex)
{
Helper.LogError(ex);
}
finally
{
lockdownTimer.Start();
calloutsReminderTimer.Start();
}
}
这是退出菜单项的代码:
private void fileExitMenuItem_Click(object sender, System.EventArgs e)
{
Application.Exit();
}
当从上面调用 LockApplication 方法中的以下行时,我得到 NullReferenceException:
fileExitMenuItem.PerformClick();
[更新 2] 执行上述行时调用堆栈信息:
[External Code]
Cudos.exe!Cudos.mainForm.LockApplication() 第 1132 行 + 0x10 字节 C# Cudos.exe!Cudos.mainForm.fileLockCudosMenuItem_Click(object sender, System.EventArgs e) 第 1594 行 + 0x8 字节 C# [外部代码] Cudos.exe!Cudos .mainForm.Main() 第 1880 行 + 0x1d 字节 C# [外部代码]