3

クリーンな WindowsFormsApplication ソリューションを作成ToolStripし、メイン フォームに を追加して、ボタンを 1 つ配置しました。OpenFileDialogClickイベントがToolStripButton次のようになるように、も追加しました。

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

他のプロパティやイベントは変更しませんでした。

面白いことに、ダブルクリックするとToolStripButton(ダイアログが開く前に 2 回目のクリックは非常に速くなければなりません)、両方のダイアログをキャンセルし (またはファイルを選択します。実際には関係ありません)、クライアント領域をクリックします。メイン フォームの場合、NullReferenceExceptionアプリケーションがクラッシュします (エラーの詳細は投稿の最後に添付されています)。イベントは実装されていませんが、実装されていないことに注意してくださいClickDoubleClick

OpenFileDialogをユーザーが実装したフォームに置き換えると、 が2ToolStripButton 回クリックされなくなります

最新の更新プログラムを使用して、 Windows 7 Professional (MSDNAA から) で.NET3.5 を使用して VS2008 を使用しています。VS では多くのオプションを変更しませんでした (フォントサイズ、ワークスペース フォルダー、および行番号のみ)。

これを解決する方法を知っている人はいますか?私のマシンでは 100% 複製可能ですが、他のマシンでも再現できますか?

私が考えることができる 1 つの解決策は、呼び出す前にボタンを無効にしてから、ボタンOpenFileDialog.ShowDialog()を有効にして戻すことです (ただし、これは適切ではありません)。他のアイデアはありますか?

そして今、約束されたエラーの詳細:

System.NullReferenceException は処理
されませんでした Message="オブジェクト参照がオブジェクトのインスタンスに設定されていません。"
Source="System.Windows.Forms"
StackTrace:
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 remove)
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 理由、
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:
System.AppDomain._nExecuteAssembly(アセ​​ンブリ アセンブリ、String[] args)の行 20
System.AppDomain.ExecuteAssembly(String assemblyFile、Evidence assemblySecurity、String[] args)
で Microsoft.VisualStudio .HostingProcess.HostProc.RunUsersAssembly()
で System.Threading.ThreadHelper.ThreadStart_Context (オブジェクト状態)
System.Threading.ExecutionContext.Run (ExecutionContext executionContext、ContextCallback コールバック、オブジェクト状態)
で System.Threading.ThreadHelper.ThreadStart() で
InnerException:

4

3 に答える 3

2

Windows 7マシンでこのようなものを複製することができました-例外はありませんが、フォームは再描画されなくなります。例外が飲み込まれているのは、win7ボックスのデバッガーで実行していないためである可能性があります。

これは私のXPマシンでは起こりません。これは、toolStripButtonを使用して、ダイアログを初めて開いたときにそれをダブルクリックしたときにのみ発生しました。ダイアログを通常どおり開いてから最初に閉じた場合、ダブルクリックしてもダイアログが2回開かれません。

ここで起こっていることは、競合状態にていると思います。フレームワーク開発者は、コードが2回入力されるとは予想していませんでしたが、メッセージループへの新しい呼び出しが原因で発生しました。それで、なぜこれが起こっているのですか?私にはバグのように見えます。

それが起こらないようにする非常に簡単な回避策の1つを見つけました-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

フレームワークでエラーが発生する原因の 1 つは、画面の解像度です。私の場合、画面の解像度を変更しましたが、その解像度では問題は発生しませんでした。推奨される解像度に戻すと、問題が発生しました。

于 2016-06-15T07:12:39.503 に答える