web-dev-qa-db-ja.com

Winformの右上にある「X」閉じるボタンの動作をどこで制御しますか?

一部のフォームをモードレスにすることで、VB.NETアプリケーションを少し使いやすくすることに挑戦しています。

Dlg.ShowDialog()を呼び出す代わりに、dlg.Show()とdlg.Hide()を使用する方法を理解したと思います。メインアプリケーションフォームにモードレスダイアログのインスタンスがあります。

Public theModelessDialog As New dlgModeless

私が呼び出すモードレスダイアログを起動するには

theModelessDialog.Show()

dlgModelessの[OK]ボタンと[キャンセル]ボタンハンドラ内に

Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
    Me.DialogResult = System.Windows.Forms.DialogResult.OK
    Me.Hide()
End Sub

Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
    Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
    Me.Hide()
End Sub

そしてそれはうまくいくようです。

右上の「X」ボタンを押しても気になりません。そのボタンでフォームを閉じてから、フォームを再度開こうとすると、

ObjectDisposedExceptionが処理されませんでした。破棄されたオブジェクトにアクセスできません。

私はほとんどそこにいるように感じますが、次のいずれかを行う方法を理解できません。

  • その「X」ボタンを非表示にする
  • オブジェクトを破棄しないようにイベントをキャッチします([キャンセル]を押すのと同じように扱います)

何か案は?

このダイアログのクラスはSystem.Windows.Forms.Form

16
John

フォームを非表示にするには、Me.Close()を使用します。それを開くには、次のスニペットを使用します。

If theModelessDialog.IsDisposed Then
    theModelessDialog = New dlgModeless
End If
dlgModeless.Show()

これがデータを保存する場合は、データを保存する方法を(おそらくフォームの静的変数に)把握する必要があります。これは、あなたが達成しようとしていることを行うための適切な方法です。

私のVBがオフになっている場合も、しばらくの間私を許す必要があります。

4

FormClosingイベントをキャッチし、理由がUserClosingの場合は、イベントのCancelをtrueに設定します。

次のようなもの:

Private Sub Form1_FormClosing(sender as Object, e as FormClosingEventArgs) _ 
     Handles Form1.FormClosing

    if e.CloseReason = CloseReason.UserClosing then
        e.Cancel = true
        Me.Hide()
    end if

End Sub
21
Michael Todd

formclosedイベントを使用すると、フォームのマネージ終了を実行できるため、終了を確認するための質問を含めました。また、フォームフラグbterminateを使用して、キャンセルしたい場所で強制的にキャンセルするため、質問をしません。あなたの提案に感謝します:)

    Dim msgboxresponse As MsgBoxResult

    If e.CloseReason = CloseReason.UserClosing Then
        If Not Me.bTerminate Then
            msgboxresponse = MsgBox("Are you sure you want to cancel adding?", _
                                MsgBoxStyle.Question + MsgBoxStyle.YesNo, Me.Text)
            If msgboxresponse <> MsgBoxResult.Yes Then
                e.Cancel = True
                Return
            End If
        End If
    End If
1
Philip

@ John は彼のコードでフォームを非表示にしており、上記の回答はその場合の解決策を提供します。ただし、多くの場合、フォームを再度使用する予定がないため、実際には 行う フォームを破棄したい。既に持っているanyCancel/Close/ExitコードにMe.FormClosingを使用してFormClosingイベントを処理する場合、すべてのClose関連アクティビティは1か所にあります。例えば@ジョンの場合:

Private Sub Cancel_Button_Click(ByVal sender As System.Object, _ 
                                     ByVal e As System.EventArgs) _
                                 Handles Cancel_Button.Click, Me.FormClosing
....More code
Me.Dispose
End Sub

既存のMe.DisposeではなくMe.Closeを使用していることに注意してください。 Me.Closeを離れると、無限ループが発生します。 CloseとDisposeの微妙な違いについてはこちら を参照してください。

1
Neil Dunlop

私はすべてを試しましたが、メッセージボックスを表示せずに閉じたいだけではうまくいきませんでした:

Private Sub FORM1_FormClosing(sender As Object、e As FormClosingEventArgs)Handles Me.FormClosing

 >e.Cancel = False
 >FORM2.Show()   (if you want to show another form)

End Sub

これがあなたに役立つことを願っています...!

0
Esther Hearne

FormClosingイベントの処理に同意します。または、フォームのプロパティを変更して、システムXコントロールを非表示にします。

0
Robert McBean