SoapFormatter Help

Visual Studio143
I have an error that I have not been able to find. Any

insight you can offer would be most appreciated. I

believe that the problem is associated with the

SoapFormatter.



The application allows the user to document a collection

of art objects. Each object is stored in an arrayList as

an objArt. To simplify finding my problem, I have

eliminated all the code except the code for six buttons,

the Title and Description textboxes and the Photograph

picturebox. The buttons allow the user to display the

first (|<),previous (<),next (>) and last (>|) objects in

the arrayList. The two additional buttons add (+) a new

object and delete (X) the current object. The buttons

are working fine. As the user navigates to a different

record any changes to the textboxes is saved to the

arrayList. When the application is closed the arrayList

is serialized with the SoapFormatter and written to a

file. I have included an open file dialog which is

accessed by double clicking on the picturebox. The JEPG

filename is displayed in the Description textbox and the

image is sized and displayed in the picturebox.



My problem is: If I use the open file dialog to change

the Description textbox the changes to the arrayList are

NOT saved when the application closes. If I manually

edit the Description textbox the changes are saved to the

file when the application closes. I have stepped through

the code when the application closes and I have observed

that in either case the changes have been made to the

arrayList and the SaveFile routine is called.



Here is the code with the nonessential routines minimized:



Imports System.IO

Imports System.Collections

Imports System.Runtime.Serialization.Formatters.Soap

'*********************************************************

Public Class Form1

'********************************************************

Inherits System.Windows.Forms.Form

Public SGWArt As New classArt



#Region " Windows Form Designer generated code "



+ Private Sub Form1_Load(ByVal sender As System.Object,

_

ByVal e As System.EventArgs) Handles MyBase.Load .



Private Sub Form1_Closing(ByVal sender As Object, _

ByVal e As

System.ComponentModel.CancelEventArgs) _

Handles MyBase.Closing

SGWArt.SaveArt(Form2Art)

SGWArt.displayArtList() 'added to assist debug!

SGWArt.SaveFile()

SGWArt = Nothing

Beep()

End Sub



Private Sub BtnAdd_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles

BtnAdd.Click

SGWArt.AddArt()

SGWArt.SetIndx(SGWArt.ArtCount - 1)

Art2Form(SGWArt.GetArt())

StatusUpdate()

End Sub



+ Private Sub BtnDel_Click(ByVal sender As

System.Object, _

ByVal e As System.EventArgs) Handles

BtnDel.Click.



+ Sub StatusUpdate().



Sub Art2Form(ByVal MyArt As objArt)

With MyArt

tbTitle.Text = .Title

tbDesc.Text = .Des

pbPict.Text = .Pic

End With

DisplayJPG()

End Sub



Function Form2Art() As objArt

Dim MyArt As New objArt

With MyArt

.Title = tbTitle.Text

.Des = tbDesc.Text

.Pic = pbPict.Text

End With

Form2Art = MyArt

MyArt = Nothing

End Function



+ Private Sub BtnFirst_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles

BtnFirst.Click.



+ Private Sub BtnLast_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles

BtnLast.Click.



+ Private Sub BtnPrevious_Click(ByVal sender As Object,

_

ByVal e As System.EventArgs) Handles

BtnPrevious.Click.



Private Sub BtnNext_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles

BtnNext.Click

SGWArt.SaveArt(Form2Art)

If SGWArt.GetIndx < SGWArt.ArtCount - 1 Then

SGWArt.SetIndx(SGWArt.GetIndx + 1)

Art2Form(SGWArt.GetArt)

StatusUpdate()

End If

End Sub



Sub DisplayJPG()

Dim MyImage As Image

Dim MyWidth As Integer

Dim MyHeight As Integer

Dim pbArtSize As Integer

If System.IO.File.Exists(tbDesc.Text) Then

MyImage = Image.FromFile(tbDesc.Text)

pbArtSize = pbPict.Width 'Note pbArt must be

square

MyWidth = MyImage.Width

MyHeight = MyImage.Height

'Set the width & height of the thumbnail

If MyWidth>MyHeight Then

MyHeight = pbArtSize * MyHeight / MyWidth

MyWidth = pbArtSize

Else

MyWidth = pbArtSize * MyWidth / MyHeight

MyHeight = pbArtSize

End If

MyImage = MyImage.GetThumbnailImage(MyWidth,

MyHeight, _

Nothing, New IntPtr)

pbPict.Image = MyImage

Else

pbPict.Image = Nothing

End If

End Sub



Private Sub pbPict_DoubleClick(ByVal sender As

Object, _

ByVal e As System.EventArgs) Handles

pbPict.DoubleClick

If jpgDialog.ShowDialog = DialogResult.OK Then

'pbPict.Text = jpgDialog.FileName

tbDesc.Text = jpgDialog.FileName

DisplayJPG()

End If

End Sub



+ Sub MyToolTips().



End Class



'*********************************************************

***

<[Serializable]()>Public Class

objArt '******

'*****************************************************

***

Public Title As String

Public Des As String

Public Pic As String

End Class



'*********************************************************

***

Public Class

classArt '******

'*****************************************************

***

Private Shared ArtList As New ArrayList 'shared added

1/5/05

Private ArtIndex As Integer

Private ArtFileName As String = "art.xml"



Public Sub SaveFile() 'save ArtList to ArtFile

Dim Msg1 As String = "ArtFile was not saved!

Reason: "

Dim Msg2 As String = "Art"

Dim sf As New SoapFormatter

Dim fs As New FileStream(ArtFileName,

FileMode.Create)

Try

sf.Serialize(fs, ArtList)

Catch ex As Exception

MsgBox(Msg1 & ex.Message,

MsgBoxStyle.Critical, Msg2)

Finally

fs.Close()

End Try

End Sub



Public Sub GetFile() 'get ArtList from ArtFile

Dim Msg1 As String = "Failed to open ArtList!

Reason: "

Dim Msg2 As String = "Art"

If System.IO.File.Exists(ArtFileName) Then

Dim fs As New FileStream(ArtFileName,

FileMode.Open)

Dim sf As New SoapFormatter

Try

ArtList = CType(sf.Deserialize(fs),

ArrayList)

'ArtList = DirectCast(sf.Deserialize(fs),

ArrayList)

Catch ex As Exception

MsgBox(Msg1 & ex.Message,

MsgBoxStyle.Critical, Msg2)

Finally

fs.Close()

sf = Nothing

fs = Nothing

End Try

Else

AddArt()

End If

End Sub



Public Function GetArt() As objArt

'return Art object from ArtList at current index

GetArt = ArtList.Item(ArtIndex)

End Function



Public Sub SaveArt(ByVal MyArt As objArt)

'put MyArt into ArtList at current index

ArtList.Item(ArtIndex) = MyArt

End Sub



+ Public Sub AddArt().



+ Public Function ArtCount() As Integer.



+ Public Sub DelArt().



+ Public Function SetIndx(ByVal Indx As Integer) As

Integer.



+ Public Function GetIndx() As Integer.



Public Function prtArtList()

Dim output As String

For Each myArt As objArt In ArtList

With myArt

output = .Title & " " & .Des

End With

Next

End Function



End Class


-