Saving Files

While opening files is a function of the parent form, saving files is a function of the child forms. Typically, applications have both a Save and a Save As command. The Save command simply replaces an existing copy of a named document with a new copy; the Save As command presents a dialog box to let the user change a document’s filename before saving it.

Complicating matters slightly, if the user slects the Save command for a document that has never been named or saved, the application should treat it as if the user had selected the Save As command in order to let him select a filename and location.

Before writing the code that will take care of saving and naming the files, let’s see how the TextSaved property, which lets us know if a document needs to be saved, is modified by the program as files are changed.

The TextSaved Property

When we were setting up the child form template earlier in this chapter, we created a Boolean TextSaved property. Its job is to report whether the text contained in the child form’s text box has been saved (or if it is in need of saving). The initial value of TextSaved is True, indicating that the file has not been modified since it was last saved. However, we need to set it to False whenever any text in the text box changes to indicate that the document needs saving. This is a simple matter of adding code to the txtMain text box’s TextChanged event handler, which is invoked whenever the text in the text box changes (usually by user interaction):

1.
In the Code window for frmChild, select txtMain from the Class Name box; then slect TextChanged from the Method Name box. This will create a shell txtMain_TextChanged event handler.

2.
Add the code Me.TextSaved = False to the event handler so it looks like this:
Private Sub txtMain_TextChanged(ByVal sender As Object, _ 
    ByVal e As System.EventArgs) Handles txtMain.TextChanged 
    Me.TextSaved = False 
End Sub 



The SaveFile Procedure

As you will see, the functionality that actually writes a file to disk will need to be called from several locations; therefore, it makes sense to create a standalone SaveFile procedure in the child form class. As with the parent form, the child form’s Code window needs to include a reference to the System.IO namespace, so enter Imports System.IO at the very top of frmChild’s Code window, just above the Public Class frmChild. Then, enter the following code at the end in the Code window for the child form, just above the End Class line:

Private Sub SaveFile() 
    Dim MyFile As StreamWriter 
    If sFileName = "" Then 
        SaveFileAs() 
    End If 
    MyFile = File.CreateText(sFileName) 
    MyFile.Write(txtMain.Text) 
    MyFile.Close() 
    Me.TextSaved = True 
End Sub 

If the SaveFile procedure detects that the form’s FileName property is empty, it calls the SaveFileAs procedure, which will cause the user to be prompted for a filename and location. Notice that the SaveFile procedure sets the form’s TextSaved property to True, indicating, that the text contained in the form’s text box has been saved and is unmodified since then.

The SaveFileAs Procedure

Next, we are going to create a standalone Save As procedure that may seem a little unnecessary at first, but its purpose will become clear soon enough. The Save As procedure will simply invoke the SaveFileDialog control (dlgSave) that we created when we set up the form, using the current contents of the form’s FileName property to pre-populate the dialog box’s FileName property. Enter the following procedure in the Code window just after the SaveFile procedure:

Sub SaveFileAs() 
    dlgSave.FileName = Me.FileName 
    dlgSave.ShowDialog() 
End Sub 

Coding the Save Menu Option

When the user selects Save from the File menu, the program must determine if the user has named the file yet (as determined by examining the value of the internal sFileName variable). If so, then the SaveFile procedure is to be invoked; however, if the document is unnamed, the SaveFileAs procedure must be invoked instead, so that the user will have an opportunity to name the file. Enter the following code into the Click event handler for the mnuFileSave menu item:

Private Sub mnuFileSave_Click(ByVal sender As Object, _ 
    ByVal e As System.EventArgs) Handles mnuFileSave.Click 
    If sFileName > "" Then 
        SaveFile() 
    Else 
        SaveFileAs() 
    End If 
End Sub 

Coding the Save As Menu Option

When the user selects Save As from the File menu, she is specifically saying that she wants to be presented with the opportunity to specify a new name for the file. The following code, which is to be entered into the Click event handler for the mnuFileSaveAs menu item, will accomplish this by invoking the SaveFileAs procedure we just created (which in turn shows the SaveFileDialog box):

Private Sub mnuFileSaveAs_Click(ByVal sender As Object, _ 
    ByVal e As System.EventArgs) Handles mnuFileSaveAs.Click 
    SaveFileAs() 
End Sub 

Coding the SaveFileDialog Control

When the user is presented with the SaveFileDialog control and clicks OK, he has specified a new filename under which the document is to be saved. The following code, entered into the FileOK event handler of dlgSave, checks the value of the argument that was passed into the procedure, just to make sure the user hasn’t cancelled his request or left out the filename. If he has not, the form’s FileName property is updated with the dialog box’s FileName property, and the SaveFile procedure is invoked to actually save the file:

Private Sub dlgSave_FileOk(ByVal sender As Object, _ 
    ByVal e As System.ComponentModel.CancelEventArgs) Handles dlgSave.FileOk 
    If e.Cancel = False Then 
        Me.FileName = dlgSave.FileName 
        SaveFile() 
    End If 
End Sub 

Managing Documents when Windows Are Closed

When a user closes a child window, the program should check the TextSaved property to see if the document contained in that instance of the child window has been modified since it was last saved. If it has, the user should be given the option of saving the document before the window closes. To do this, we will add code to the child form’s Closing event handler, which is invoked after the user attempts to close the window, but before the window is actually closed. Follow these steps:

1.
In the Code window for frmChild, select (Base Class Events) from the Class Name box; then select Closing from the Method Name box. This will create a shell frmChild_Closing event handler.

2.
Enter the following code to complete the frmChild_Closing event handler:
Private Sub frmChild_Closing(ByVal sender As Object, _ 
    ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing 
    If Me.TextSaved = False Then 
        Dim sMsg As String 
        Dim nResult As Integer 
        sMsg = "Save changes to " 
        If Me.FileName = "" Then 
            sMsg += "this untitled document" 
        Else 
            sMsg += Mid(sFileName, InStrRev(sFileName, "") + 1) 
        End If 
        sMsg += " before closing it?" 
        nResult = MessageBox.Show(sMsg, "System Message", _ 
            MessageBoxButtons.YesNoCancel) 
        Select Case nResult 
            Case DialogResult.Cancel 
                e.Cancel = True 
            Case DialogResult.Yes 
                SaveFile() 
            Case Else 
                'Do nothing; let the window close. 
        End Select 
    End If 
End Sub 



This code builds a String variable named sMsg to contain a message asking the user if he wants to save the file contained in the child document window. It then displays that message as it invokes a message box, using the Yes/No/Cancel set of buttons. A Select Case statement evaluates the user’s response. If he selects Yes, the SaveFile procedure is called (which will, in turn, call SaveFileAs if necessary); if he selects Cancel, the Cancel property of the procedure’s arguments is set to True, which aborts the closing of the window; otherwise, the user selects No and the closing of the window can continue.

Coding the File/Close Menu Option

When you created the menu system for the child form, you included a Close option under the File menu. This option should serve the same purpose as if the user clicked the window’s Close button at the upper-right. The code for this is simple; place it in the Click event handler for the mnuFileClose menu item:

Me.Close() 

Testing the File Functionality

This would be a good time to save your project and test the file opening and saving functionality. Run the program and create some documents, save them, change their names by using Save As, try to close documents that have not been saved, and so on.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.138.177