I have my form checked if it's dirty when a user goes to close it. If its dirty is true, the user is asked if they would like to save the data. When they click yes, the 'save event' is called. The problem I'm having is trying to get the form to completly close after saving. At the end of the save I put in me.close(), but another form closing event is triggered. Is this the correct way to dictate having the form close immediately after saving the data or is there a better way? If it is, I must have it placed in the wrong part of my code. Immediately after the "success" dialog box is displayed, I am asked if I want to save the data again.

'FormClosing
If is_Dirty = True Then
 messagebox.show(text) =Windows.Forms.Dialogresult.Yes Then
    e.cancel = True

    Try
      'Save Event Called'
      Messagebox.show("success")
      me.close()
      Catch ex As Exception
    End Try

Dani AI

Generated

Short diagnosis: the double save prompt happens because the close was cancelled then restarted. Setting e.Cancel = True in the FormClosing handler cancels the current close; calling Me.Close() from your save routine (or from inside FormClosing) causes FormClosing to run again — and if the dirty flag wasn’t cleared you get prompted again. 's point is correct: you usually don't need to call Close() a second time if you handle saving correctly in the first FormClosing pass.

Recommended simple pattern (save synchronously, do NOT cancel the close unless the save fails):

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    If Not is_Dirty Then Exit Sub

    Dim choice As DialogResult = MessageBox.Show("Save changes before closing?", "Confirm", MessageBoxButtons.YesNoCancel)
    If choice = DialogResult.Cancel Then
        e.Cancel = True : Exit Sub
    ElseIf choice = DialogResult.Yes Then
        Try
            SaveEvent()         ' SaveEvent must set is_Dirty = False on success
        Catch ex As Exception
            MessageBox.Show("Save failed: " & ex.Message)
            e.Cancel = True
            Exit Sub
        End Try
    End If
    ' allow close to proceed (do not call Me.Close here)
End Sub

Alternative (useful for long/async saves): cancel, perform the save, set a guard flag and re-close so the second FormClosing skips the prompt.

Private closingAfterSave As Boolean = False

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    If closingAfterSave Then Exit Sub

    If is_Dirty Then
        Dim choice = MessageBox.Show("Save changes before closing?", "Confirm", MessageBoxButtons.YesNoCancel)
        If choice = DialogResult.Yes Then
            e.Cancel = True
            Try
                SaveEvent()
                closingAfterSave = True
                Me.Close()
            Catch ex As Exception
                MessageBox.Show("Save failed: " & ex.Message)
            End Try
        ElseIf choice = DialogResult.Cancel Then
            e.Cancel = True
        End If
    End If
End Sub

Checklist for : remove unconditional e.Cancel = True before saving; make sure SaveEvent() clears is_Dirty on success; avoid calling Me.Close() from deep inside the save routine unless a guard flag is set; and handle save failures by setting e.Cancel = True so the user can correct problems. This follows the same safe idea showed but adds a guarded option when an asynchronous or lengthy save is required.

Recommended Answers

All 3 Replies

Can u please show ur save event??

Once you are in the Closing event handler you don't have to call Close() again. Here is a sample from one of my projects. It maintains a book library. When the user tries to exit the app it checks if there are unsaved changes then prompts the user for what to do.

Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

    'If there are unsaved changes to the active library, ask user what to do. If    
    'there(are) unsaved changes, the titlebar will start with the string "(unsaved)"

    Dim msgTitle As String = "You have unsaved changes"
    Dim msgPrompt As String = "Do you want to save your changes before closing?" & vbCrLf _
                & vbCrLf _
                & "    Yes    - save changes and exit" & vbCrLf _
                & "    No     - discard changes and exit" & vbCrLf _
                & "    Cancel - resume application"

    If Unsaved() Then

        Select Case MsgBox(msgPrompt, vbYesNoCancel, msgTitle)

        Case vbYes      'save changes and exit                                  
            SaveBookList(Library)
            MsgBox("Library has been saved in " & Library)

        Case vbCancel   'return to application                                  
            e.Cancel = True

        Case vbNo       'discard changes and exit                               

        End Select

    End If

End Sub

Note that the default action is to close the form and exit. If the user decides to continue instead you have to cancel the close by setting e.Cancel to True.

Thank you again for your assistance Jim, I haven't gotten to your example yet, but I do see what you're talking about. Anyways, here is the formclosing event code. I'm sure it looks pretty ugly, but it has gotten me yay far.

Private Sub PFC_XPRESS_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing

        If is_Dirty = True Then

            If MessageBox.Show("Do You Wish To Save Any Data Before Closing?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) = Windows.Forms.DialogResult.Yes Then
                e.Cancel = True

                Dim OKTOSAVE As Boolean = True

                Try

                    If Not (EVENT_NUMBER.Text = "" Or Officer.Text = "") Then

                        'Call CREATE_EXCEL_FILE(outputdirectory)

                        If OKTOSAVE Then
                            'Save the Event info from form into Datatable and write to excel file
                            PFC_Xpress.Tables("Event Info").Clear()
                            Call SAVE_EVENT()
                            WRITE_TO_EXCEL(PFC_Xpress.Tables("Event Info"), True, 1) 'Write Event info from datatable to excel file

                            'Save the Person info from form into datatable and write to excel file
                            Call SAVE_PERSON()
                            WRITE_TO_EXCEL(PFC_Xpress.Tables("PERSON"), True, 2) 'Write Person info from datatable to excel file

                            'Save the Property info from form into datatable and write to excel file
                            Call Save_Property()
                            WRITE_TO_EXCEL(PFC_Xpress.Tables("PROPERTY"), True, 3) 'Write Property info from datatable to excel file

                            'Save the Vehicle info from form into datatabl and write to excel file
                            Call Save_Vehicle()
                            WRITE_TO_EXCEL(PFC_Xpress.Tables("VEHICLE"), True, 4) 'Write Vehicle info from datatable to excel file

                            Call Close_Excel(outputdirectory & Officer.Text & "_" & EVENT_NUMBER.Text & ".xlsx")


                        End If
                    Else
                        MessageBox.Show("Complete both the Officer Number and Event Number fields before saving.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Stop)
                    End If


                    'Remind Officer to turn in "attachment sheet" if the incident type is a warrant since Hit Confirmation Paperwork is recevied at front desk'
                    Try
                        If (INCIDENT_TYPE.Text = "WARRAN") Then

                            MessageBox.Show("Don't Forget Attachment Sheet", "Reminder", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                        End If

                    Catch ex As Exception

                    End Try

                Catch ex As Exception
                    Write_Log_File(ex.ToString, LOGFILENAME)
                    MessageBox.Show(ex.ToString)

                End Try

            End If

        End If

    End Sub



 Sub Close_Excel(ByRef FILENAME As String)
        'FINISH SAVING FILE AND DISPLAY SUCCESS MESSAGE BOX

        Try

            objwb.SaveAs(FILENAME)
            objwb.Close()

            MessageBox.Show("File Save Success!", "Save Success", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Me.Close()
            objxl.DisplayAlerts = False
            Marshal.ReleaseComObject(objws)
            objxl.Quit()
            Marshal.ReleaseComObject(objxl)
            objws = Nothing
            objwb = Nothing
            objwbs = Nothing
            objxl = Nothing

        Catch ex As Exception

        End Try
    End Sub
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.