VB.NET - form closing events are not acknowledging my save button

Asked By jenn on 03-May-10 01:39 PM
good morning all :)

Gotta problem here and I really dont know how to fix it.

I have a save button on a window form. Everything seems to be working fine with it. When I click on it, I get a save dialog box..and it will save the file to where I want it.

The problem is this:
After I click on the save button, and go through putting it where I want to save it. I go to close out my form, either by hitting the X..or by the Exit in the menustrip. Both ways of closing will produce a message box asking me if I want to exit without saving changes.

SO..of course I minimize my screen and go to the file I just saved and I can see the file...but it sits at 0kb. Opening the file will produce an empty sheet LOL.

This is the code I am using for my form Closing events:

Private Sub frmShopDisplay_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If MessageBox.Show("Are you sure you want to exit without saving changes?", "Exiting", _
         MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.No Then
            e.Cancel = True
        End If
    End Sub
  
  
THis is the code I have to close the form when X is used


And the exit in the menu strip is just a simple me.Close


somehow I seemed to have missed something here!
Web Star replied to jenn on 03-May-10 01:55 PM
problem in your file this may corrupt or any other problem in code at time of saving that file.
Mohan Raj Aryal replied to jenn on 03-May-10 02:09 PM
I think your both process are running under default GUI thread. So whenever you click on close in between some save process, the thread gets moved to your Form_Closing event handler. I suggest to make separate thread to handle file saving process if your file writing process takes long time (i.e. if you are writing large file). And let the GUI thread handle Closing Event.
Phivos Stylianides replied to jenn on 03-May-10 02:13 PM
Could you paste some more of your code, like for example when you save the file?
Anoop S replied to Phivos Stylianides on 03-May-10 02:41 PM
You can code your application like this way

System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If MessageBox.Show("Are you sure you want to exit without saving changes?", "Exiting", _
         MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.No Then
            e.Cancel = True
        End If
           Else
             Savebutton_Click     'call the save button click if the user want save and close the                                     ' application
    End Sub
jenn replied to Phivos Stylianides on 03-May-10 06:35 PM
okay :)

this is what I have for Form Closing event.
Private Sub frmShopDisplay_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Dim response As MsgBoxResult
        response = MsgBox("Do you want to close without saving changes?", MsgBoxStyle.Question + MsgBoxStyle.YesNo, "Confirm")
        If response = Windows.Forms.DialogResult.No Then
            e.Cancel = True
        End If
  
    End Sub
 and this is what I have for saving on a button save
Private Sub BtnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSave.Click
        Dim fileName As String = ""
        Dim dlgSave As New SaveFileDialog
        dlgSave.Filter = "Text files (*.txt)|*.txt|CSV Files (*.csv)|*.csv"
        dlgSave.AddExtension = True
        dlgSave.DefaultExt = "txt"
        If dlgSave.ShowDialog = Windows.Forms.DialogResult.OK Then
            fileName = dlgSave.FileName
            SaveToFile(fileName)
        End If
    End Sub
    Private Sub SaveToFile(ByVal fileName As String)
        If DataGridView1.RowCount > 0 AndAlso DataGridView1.Rows(0).Cells(0) IsNot Nothing Then
            Dim stream As New System.IO.FileStream(fileName, IO.FileMode.Append, IO.FileAccess.Write)
            Dim sw As New System.IO.StreamWriter(stream)
            For Each row As DataGridViewRow In DataGridView1.Rows
                Dim line As String
                line = row.Cells(0).ToString()
                line &= ";" & row.Cells(1).ToString()
                line &= ";" & row.Cells(2).ToString()
                line &= ";" & row.Cells(3).ToString()
                line &= ";" & row.Cells(4).ToString()
                line &= ";" & row.Cells(5).ToString()
                line &= ";" & row.Cells(6).ToString()
                line &= ";" & row.Cells(7).ToString()
  
            Next
            sw.Flush()
            sw.Close()
        End If
    End Sub

My combo boxes seem fine..they are displaying in the datagridview that I have but just in case, here is my combobox code ..or at least one of them..LOL...I got 8 of em, and they are all named matching the datagrid columns.

Private Sub ComboBoxDate_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        ComboBoxBay.GetItemText(ComboBoxBay.SelectedItem)
    End Sub
Phivos Stylianides replied to jenn on 03-May-10 06:53 PM
Look at your code in the SaveToFile method. You are opening the file stream, creating the StreamWriter, saving the grid contents to a string and then closing both streams. Instead of using the string 'line' you need to do sw.Write(row.Cells(0).ToString()) for each cell and at the end of the for loop this sw.WriteLine("") to start a new line, to actually write the contents of the cells to the file.
jenn replied to Phivos Stylianides on 03-May-10 07:21 PM
okay I dont quite fully understand. LOL (which is not all that amazing!)

This is what I did:
Private Sub SaveToFile(ByVal fileName As String)
        If DataGridView1.RowCount > 0 AndAlso DataGridView1.Rows(0).Cells(0) IsNot Nothing Then
            Dim stream As New System.IO.FileStream(fileName, IO.FileMode.Append, IO.FileAccess.Write)
            Dim sw As New System.IO.StreamWriter(stream)
            For Each row As DataGridViewRow In DataGridView1.Rows
                Dim line As String
                sw.Write(row.Cells(0).ToString())
                sw.Write(row.Cells(1).ToString())
                sw.Write(row.Cells(2).ToString())
                sw.Write(row.Cells(3).ToString())
                sw.Write(row.Cells(4).ToString())
                sw.Write(row.Cells(5).ToString())
                sw.Write(row.Cells(6).ToString())
                sw.Write(row.Cells(7).ToString())
  
            Next
            sw.Flush()
            sw.Close()
        End If
    End Sub

And I have an error on the line Dim line As String   
it is telling me it is an unused local variable.  So I tried to take line out and replace it with a couple of different ones. I used row, and row.cells and it didnt like any one of them either LOL

I dont understand where I am suppose to put sw.WriteLine("") ?

is this suppose to be after one line and before starting another??

 
Phivos Stylianides replied to jenn on 03-May-10 07:28 PM
Yes the sw.WriteLine("") is used to start a new line in the text file. You don't need this: Dim line As String.
So the code becomes:

Private Sub SaveToFile(ByVal fileName As String)
        If DataGridView1.RowCount > 0 AndAlso DataGridView1.Rows(0).Cells(0) IsNot Nothing Then
            Dim stream As New System.IO.FileStream(fileName, IO.FileMode.Append, IO.FileAccess.Write)
            Dim sw As New System.IO.StreamWriter(stream)
            For Each row As DataGridViewRow In DataGridView1.Rows
                sw.Write(row.Cells(0).ToString())
                sw.Write(";" & row.Cells(1).ToString())
                sw.Write(";" & row.Cells(2).ToString())
                sw.Write(";" & row.Cells(3).ToString())
                sw.Write(";" & row.Cells(4).ToString())
                sw.Write(";" & row.Cells(5).ToString())
                sw.Write(";" & row.Cells(6).ToString())
                sw.Write(";" & row.Cells(7).ToString())
        sw.WriteLine("")
            Next
            sw.Flush()
            sw.Close()
        End If
    End Sub
jenn replied to Phivos Stylianides on 03-May-10 08:54 PM
Well I just dont get it :(

it shows me a file size of 2kb after debug test but when I open the file to see if the contents of the gridview is there..this is what is there LOL

DataGridViewTextBoxCell { ColumnIndex=0
DataGridViewTextBoxCell { ColumnIndex=1
DataGridViewTextBoxCell { ColumnIndex=2
DataGridViewTextBoxCell { ColumnIndex=3
DataGridViewTextBoxCell { ColumnIndex=4
DataGridViewTextBoxCell { ColumnIndex=5
DataGridViewTextBoxCell { ColumnIndex=6
DataGridViewTextBoxCell { ColumnIndex=7
DataGridViewTextBoxCell { ColumnIndex=0
DataGridViewTextBoxCell { ColumnIndex=1
DataGridViewTextBoxCell { ColumnIndex=2
DataGridViewTextBoxCell { ColumnIndex=3
DataGridViewTextBoxCell { ColumnIndex=4



This is what my code looks like now:
Private Sub SaveToFile(ByVal fileName As String)
        If DataGridView1.RowCount > 0 AndAlso DataGridView1.Rows(0).Cells(0) IsNot Nothing Then
            Dim stream As New System.IO.FileStream(fileName, IO.FileMode.Append, IO.FileAccess.Write)
            Dim sw As New System.IO.StreamWriter(stream)
            For Each row As DataGridViewRow In DataGridView1.Rows
                sw.Write(row.Cells(0).ToString())
                sw.WriteLine("")
                sw.Write(row.Cells(1).ToString())
                sw.WriteLine("")
                sw.Write(row.Cells(2).ToString())
                sw.WriteLine("")
                sw.Write(row.Cells(3).ToString())
                sw.WriteLine("")
                sw.Write(row.Cells(4).ToString())
                sw.WriteLine("")
                sw.Write(row.Cells(5).ToString())
                sw.WriteLine("")
                sw.Write(row.Cells(6).ToString())
                sw.WriteLine("")
                sw.Write(row.Cells(7).ToString())
                sw.WriteLine("")
            Next
            sw.Flush()
            sw.Close()
        End If
    End Sub


at least it is not sitting at 0kb anymore tho :)
Phivos Stylianides replied to jenn on 03-May-10 09:00 PM
Yes sounds about right! I just realized that you output the ToString of the cell itself and not the cell's value!

Instead of this:
sw.Write(row.Cells(0).ToString())
use this:
sw.Write(row.Cells(0).Value.ToString())
jenn replied to Phivos Stylianides on 03-May-10 09:23 PM
heheheheee..well that sounds about like me! LOL

anywayz, this is what was typed
f DataGridView1.RowCount > 0 AndAlso DataGridView1.Rows(0).Cells(0) IsNot Nothing Then
            Dim stream As New System.IO.FileStream(fileName, IO.FileMode.Append, IO.FileAccess.Write)
            Dim sw As New System.IO.StreamWriter(stream)
            For Each row As DataGridViewRow In DataGridView1.Rows
                sw.Write(row.Cells(0).Value.ToString())
                sw.WriteLine("")
                sw.Write(row.Cells(1).Value.ToString())

An error : object reference not set to an instance of an object.  ( I kinda understand that, but not really)
This error was on the sw.Write(row.Cells(0).Value.ToString()) line

The trouble shooter told me:
use the "new" keyword to create an object instance
OR
Check to determine if the object is null before calling the method

and btw, thank you for helping me with this :)- have been on this for over a week already sheeeeeeeeeeeesh!
Phivos Stylianides replied to jenn on 03-May-10 09:46 PM
This error is likely to occur if any of the row cells are empty. Before calling the ToString method to your cell's value you should check that value if it's null and in that case go to the next cell. Here is how you do it: (I also added a second for loop that iterates each row's cells, it makes lines of code less)

Private Sub SaveToFile(ByVal fileName As String)
        If DataGridView1.RowCount > 0 Then
            Dim stream As New System.IO.FileStream(fileName, IO.FileMode.Append, IO.FileAccess.Write)
            Dim sw As New System.IO.StreamWriter(stream)
            For Each row As DataGridViewRow In DataGridView1.Rows
                For Index As Integer = 0 To row.Cells.Count - 1
                    If row.Cells(Index).Value IsNot Nothing Then
                        sw.Write(row.Cells(Index).Value.ToString())
                    End If
                    sw.WriteLine("")
                Next
            Next
            sw.Flush()
            sw.Close()
        End If
    End Sub
jenn replied to Phivos Stylianides on 03-May-10 10:01 PM
haaaaaaaaaaaaaaaaaaaaaaaaaaaaaa! :)

okay LOL...me thinks ya got it!

I can at least see my entries from the datagridview WOOOOOOOHOO!!

but LOL..and this maybe just plain ignorance on my end or im just being waaaaay to picky

the file does save to excel :)

but the fields are all in one column...like this:

John Hanson
8:15AM
Bay 5
Mary Bergen
1 hour
balance
waiting
10:00 AM


And really that is all fine and dandy if it must be that way ( this has been a fight to even get it this far)

can I go into excel and type the field names in and some how get the gridview to put them in their proper fields??

here are my column names in gridview:

Employee
Time In
Bay Number
Customer Name
Estimated Proj. Time
Task
Status
Finish Time

or am I opening up yet another weeks worth of can of worms here LOL
jenn replied to Phivos Stylianides on 03-May-10 10:02 PM
ooooO..i meant to mark this post as helpful to me so dont think I am double posting..just forgot ta give credit is all :)