3

我创建了一个干净的 WindowsFormsApplication 解决方案,ToolStrip在主窗体中添加了一个,并在其上放置了一个按钮。我还添加了一个OpenFileDialog,因此Click事件ToolStripButton如下所示:

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

我没有更改任何其他属性或事件。

好笑的是当我双击的时候ToolStripButton(第二次点击一定很快,在对话框打开之前),然后取消两个对话框(或者选择一个文件,没关系)然后在客户区点击在主窗体中,NullReferenceException应用程序崩溃(帖子末尾附有错误详细信息)。请注意,该Click事件已实施,DoubleClick而未实施。

更奇怪的OpenFileDialog是,当替换为任何用户实现的表单时,ToolStripButton 阻止被点击两次

我在最新更新的Windows 7 Professional(来自 MSDNAA)上使用 VS2008 和 .NET3.5。我没有更改 VS 中的许多选项(仅字体大小、工作区文件夹和行号)。

有谁知道如何解决这个问题?它在我的机器上是 100% 可复制的,在其他机器上也可以吗?

我能想到的一种解决方案是在调用之前禁用按钮OpenFileDialog.ShowDialog(),然后重新启用按钮(但这并不好)。还有其他想法吗?

现在承诺的错误详细信息:

System.NullReferenceException 未处理
Message="对象引用未设置为对象的实例。"
Source="System.Windows.Forms"
StackTrace:在 System.Windows.Forms.UnsafeNativeMethods.PeekMessage 的 System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg
, IntPtr wparam, IntPtr lparam)
HandleRef hwnd, Int32 msgMin, Int32 msgMax, Int32 remove)
在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
在 System.Windows.Forms .Application.ThreadContext.RunMessageLoopInner(Int32 原因,
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.Run(Form mainForm)
在 WindowsFormsApplication1.Program.Main() w C:\Users\Marchewek\Desktop \Workspaces\VisualStudio\WindowsFormsApplication1\Program.cs:第 20 行
System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio
System.Threading.ThreadHelper.ThreadStart_Context(对象状态)处的.HostingProcess.HostProc.RunUsersAssembly( )
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
InnerException:

4

3 回答 3

2

我能够在 Windows 7 机器上复制这样的东西 - 我没有例外,但我的表单将不再重绘。可能是因为我没有在 win 7 机器上的调试器中运行,所以异常被吞没了。

这不会发生在我的 XP 机器上。这只发生在我第一次打开对话框时使用 toolStripButton 并双击它时。如果我正常打开对话框然后先关闭它,则双击不会打开对话框两次。

怀疑这里发生的事情类似于竞态条件——框架开发人员从没想过他们的代码会被输入两次,但这是由于对消息循环的新调用而发生的。那么为什么会发生这种情况 - 对我来说看起来像是一个错误。

我找到了一种非常简单的解决方法来阻止它发生 - 启用 toolStripButton 的 DoubleClickEnabled 属性。您不必实现双击处理程序 - 它将双击视为单击然后一切正常。

我会这样处理:

    public Form1()
    {
        InitializeComponent();

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

    }

下次升级框架时,您可以尝试将其删除。

尼尔

于 2011-01-11T18:31:30.513 回答
0

ShowDialog 方法是模态的。通常在调用 ShowDialog 之后,OpenFileDialog 拥有应用程序的专有 UI 焦点,直到对话框关闭。

通过快速双击按钮,您将在框架有机会给 OpenFileDialog 专有 UI 焦点之前再次调用 ShowDialog。这使您的应用程序处于无效状态。

虽然这不应该是可能的,但显然它是,现在这是你的问题。订阅按钮的 Click 事件并在第一次单击后禁用按钮;或从设计器中删除 OpenFileDialog 并在 Click 处理程序中以编程方式创建它。如果您执行后者,请将其包装在 using 块中以确保垃圾回收:

private void toolStripButton1_Click(object sender, EventArgs e)   
{
    using(var OFD = new OpenFileDialog())
    {
        OFD.ShowDialog();  
    } 
} 
于 2011-01-11T19:31:14.203 回答
0

屏幕分辨率可能是导致框架出错的原因之一。就我而言,我更改了屏幕分辨率,但该分辨率并未产生问题,当我切换回推荐的分辨率时,我遇到了问题。

于 2016-06-15T07:12:39.503 回答