0

コントロールのリストで構築されたフォームがあります。ただし、これらのコントロールを削除して再構築することにより、これらのコントロールのデータを更新します。これは、それが敏感になるところです。すべてのコントロールを再構築するためにクリーニング関数を呼び出す前のテキストボックスからの leave イベントをトリガーする別のテキストボックスを最初にクリックすると、エラーが発生します。クリックしたテキストボックスが破棄されたアイテムのリストに含まれているため、「という名前の破棄されたオブジェクトにアクセスできません」というエラーが発生します。ただし、フォームの作成時に System.ObjectDisposedException をキャッチできないため、 System.ObjectDisposedException を処理する場所がわかりません。

クラッシュログはこちら

 System.ObjectDisposedException: Can not access a disposed object named "TextBox".
Object name: "TextBox".
    Has System.Windows.Forms.Control.CreateHandle ()
    Has System.Windows.Forms.TextBoxBase.CreateHandle ()
    Has System.Windows.Forms.Control.get_Handle ()
    Has System.Windows.Forms.Control.set_CaptureInternal (Boolean value)
    Has System.Windows.Forms.Control.WmMouseDown (Message & m, MouseButtons button, Int32 clicks)
    at System.Windows.Forms.Control.WndProc (Message & m)
    Has System.Windows.Forms.TextBoxBase.WndProc (Message & m)
    Has System.Windows.Forms.TextBox.WndProc (Message & m)
    Has System.Windows.Forms.ControlNativeWindow.OnMessage (Message & m)
    Has System.Windows.Forms.ControlNativeWindow.WndProc (Message & m)
    at System.Windows.Forms.NativeWindow.Callback (IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

私もステートメントを使用しようとしますif Control.Isdisposed then returnが、 leave または mousedown イベントはそれを気にしないようです:S

このフォームでこのエラーを処理できる場所を見つけるのを手伝ってもらえますか。End Sub の後にポップアップするだけでデバッグできません。

vb.net FrameWorks 1.1 でのコーディング

これが目的のオブジェクトを破壊する私のコードです

Private Sub viderRecursiveStack(ByVal control As Control)
        Dim stack As New stack
        Dim ctl As control
        Dim enfantAssocie As ArrayList


        stack.Push(control)

        While stack.Count > 0

            ctl = CType(stack.Pop, control)


            If Not ctl Is Nothing Then

                If TypeOf ctl Is Panel Then

                    'Cree la liste des enfants associés
                    enfantAssocie = New ArrayList(ctl.Controls)

                    For Each ctli As control In enfantAssocie

                        If Not TypeOf ctli Is EasyDeal.Controls.EasyDealLabel3D AndAlso** Not TypeOf ctli Is EasyDeal.Controls.EasyDealButton Then
                            stack.Push(ctli)
                            ctl.Controls.Remove(ctli)
                        End If

                    Next

                Else
                    RemoveHandler ctl.Leave, AddressOf txtEquipAddCommissionChanged
                    ctl.Dispose()
                End If

            End If

        End While

    End Sub
4

1 に答える 1

0

コントロールを「削除」するときは、次のすべてをこの順序で実行する必要があります。

  1. コントロールからすべてのイベント ハンドラーを削除します。
  2. Controls親のコレクションのコントロールからコントロールを削除します
  3. Disposeコントロールでメソッドを呼び出す

しかし、この場合、これらすべてを行っていますが、独自のイベントからコントロールを削除しようとしているため、まだ問題があります。そもそも例外の取得を回避したい場合は、その場合は、後でそのコントロールで dispose を呼び出すのを待つことをお勧めします。ステップ 2 の後、コントロールを というプライベート フィールドに追加できます_controlsToDispose As List(Of Control)。次に、フォームのアンロード イベント、タイマー、または他のコントロールからの他のイベントで、そのリストで破棄するためにキューに入れられたコントロールをループして処理することができます。

MyApplication_UnhandledExceptionただし、物事をそのままにし、例外が発生したときに無視したい場合は、イベントハンドラーでそれを行うことができるはずです。そこに到達するには、プロジェクトのプロパティを開き、[アプリケーション] タブに移動してから、ページの下部にあるアプリケーション フレームワーク フレームの [アプリケーション イベントの表示] ボタンをクリックします。ただし、これは、アプリケーション フレームワークが有効になっている場合にのみ使用できます。アプリケーションの独自のエントリ ポイントを作成し、自分自身を呼び出している場合はApplication.Run、その呼び出しの周りに try catch ブロックを配置するだけで、そこでキャッチできるはずです。

于 2012-07-11T13:43:45.303 に答える