J
Jamie Noble
I am experiencing the following problem and I could really use some
assistance.
Basically I have created a class called PhaseDescription. This class
has the following three private members, Name, Description and
ImageFile.
I also have a class called Phases which contains an array of
PhaseDescription objects. There are also additional subroutines in the
class.
Finally in my program I have a public variable called PhaseList that
is defined as follows in my main code module.
Public PhasesList As Phases = New Phases()
I then have a form called frmEditPhase that is used to work with this
variable. When the form loads it populates a combo box on the form
called cmbPhaseName with the names of the objects contained by the
PhasesList variable.
On initial load into the form everything works fine and the objects
contain the correct information that they loaded with. However if I
just strictly manipulate the combo box after loading the form then
after three or four selections I will lose the ImageFile reference.
The ImageFile is a string variable that contains the filename of a jpg
image. The description string however continues to keep it's
information while the ImageFile string gets reset to NONE.
I have a second set of objects that are 99% identical to keep athlete
records. Those two objects work fine! I have even taken those objects
and performed the bare minimum needed to convert them to Phases and
PhaseDescriptions. The problem still existed so I then modified the
selected index code to mirror what's in use in the form Athlete that
works fine.
I have use breaks and watched the progress through the code as well. I
honestly cannot see why I am loosing the reference.
Does anyone have any suggestions on what is going on here. It reminds
me of memory pointer issues in C++ but the fact that the descriptions
are being preserved while the imagefile info in the same object is
being lost has me stumped.
Any suggestions? (Code follows).
~Jamie N
Private Sub frmEditPhase_Load(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles MyBase.Load
Dim iTempCounter As Integer
Dim aSkillNames() As String
cmbPhaseName.Sorted = True
PhasesList.PopulateNamesComboBox(cmbPhaseName)
If PhasesList.NumberPhases > -1 Then
cmbPhaseName.SelectedItem = PhasesList.GetFirstPhaseName
End If
End Sub
Private Sub cmbPhaseName_SelectedIndexChanged(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
cmbPhaseName.SelectedIndexChanged
Dim sImageFileName As String
Dim sLevelName As String
Dim iLoopCounter As Integer
Dim TempPhase As PhaseDescription = New PhaseDescription()
TempPhase = PhasesList.View(cmbPhaseName.SelectedItem)
txtPhaseDescription.Text = TempPhase.Description
If TempPhase.ImageFile = "NONE" Then
picSkillShot.Image = Nothing
Else
picSkillShot.Image = Image.FromFile(TempPhase.ImageFile)
End If
' cmbPhaseName.SelectedItem = TempPhase.Name
TempPhase = Nothing
' CommentsList.PopulateCommentsListBox(cmbPhaseName.SelectedItem,
lstSkillComments)
End Sub
Imports System.Xml
Imports System.Xml.Xsl
Imports System.IO
Public Class Phases
Private PhaseArray(-1) As PhaseDescription
ReadOnly Property NumberPhases() As Integer
' Returns the actual number of comments available in zero
based notation.
' Add one to the answer if you want to think numbers the way
people do.
Get
Return PhaseArray.GetUpperBound(0)
End Get
End Property
Public Sub Add(ByVal TempPhase As PhaseDescription)
Dim iNumPhases As Integer = NumberPhases
iNumPhases += 1
ReDim Preserve PhaseArray(iNumPhases)
PhaseArray(iNumPhases) = New PhaseDescription()
PhaseArray(iNumPhases) = TempPhase
End Sub
Public Sub Delete(ByVal sName As String)
Dim iLoopCounter As Integer
Dim iOrigLastElement As Integer
Dim iFoundComment As Integer = -1
iOrigLastElement = NumberPhases
For iLoopCounter = 0 To iOrigLastElement
If PhaseArray(iLoopCounter).Name.ToUpper = sName.ToUpper
Then
iFoundComment = iLoopCounter
Exit For
End If
Next
If iFoundComment > -1 Then
iOrigLastElement -= 1
For iLoopCounter = iFoundComment To iOrigLastElement
PhaseArray(iLoopCounter) = PhaseArray(iLoopCounter +
1)
Next
ReDim Preserve PhaseArray(iOrigLastElement)
'AthleteArray(iOrigLastElement + 1) = Nothing
End If
End Sub
Public Function GetFirstPhaseName() As String
If NumberPhases > -1 Then
Return PhaseArray(0).Name
Else
Return "NONE"
End If
End Function
Public Sub LoadXML(ByVal sFileName As String)
Dim xtr As New XmlTextReader(sFileName)
Dim iReturnCode As Integer = 0
'Dim TempAthlete As New Athlete()
If File.Exists(sFileName) = True Then
While Not xtr.EOF
Dim TempPhase As PhaseDescription = New
PhaseDescription()
iReturnCode = TempPhase.LoadXML(xtr)
If iReturnCode = 0 Then
Add(TempPhase)
TempPhase = Nothing
End If
End While
'MessageBox.Show(iAthleteCounter & " objects loaded",
"Number of Athlete Objects")
xtr.Close()
xtr = Nothing
End If
End Sub
Public Sub PopulateNamesListBox(ByRef PhasesListbox As ListBox)
Dim iLoopCounter As Integer
PhasesListbox.Items.Clear()
For iLoopCounter = 0 To NumberPhases
PhasesListbox.Items.Add(PhaseArray(iLoopCounter).Name)
Next
End Sub
Public Sub PopulateNamesComboBox(ByRef PhaseComboBox As ComboBox)
Dim iLoopCounter As Integer
PhaseComboBox.Items.Clear()
For iLoopCounter = 0 To NumberPhases
PhaseComboBox.Items.Add(PhaseArray(iLoopCounter).Name)
Next
End Sub
Public Sub SaveXML(ByVal sFileName As String)
Dim xtw As New XmlTextWriter(sFileName,
System.Text.Encoding.UTF8)
Dim iLoopCounter As Integer
xtw.Formatting = Formatting.Indented
xtw.Indentation = 2
xtw.QuoteChar = """"c
xtw.WriteStartDocument(True)
xtw.WriteStartElement("PhaseList")
For iLoopCounter = 0 To NumberPhases
PhaseArray(iLoopCounter).SaveXML(xtw)
Next
xtw.WriteEndElement()
xtw.WriteEndDocument()
xtw.Close()
xtw = Nothing
End Sub
Public Function View(ByVal sName As String) As PhaseDescription
Dim iLoopCounter As Integer
For iLoopCounter = 0 To NumberPhases
If PhaseArray(iLoopCounter).Name.ToUpper = sName.ToUpper
Then
Return PhaseArray(iLoopCounter)
Exit Function
End If
Next
End Function
Public Sub Edit(ByVal TempPhase As PhaseDescription)
Delete(TempPhase.Name)
Add(TempPhase)
End Sub
Public Function PhaseExists(ByVal sName As String) As Boolean
Dim iOrigLastElement As Integer
Dim iLoopCounter As Integer
iOrigLastElement = NumberPhases
For iLoopCounter = 0 To iOrigLastElement
If PhaseArray(iLoopCounter).Name.ToUpper = sName.ToUpper
Then
Return True
End If
Next
Return False
End Function
End Class
Imports System.IO
Imports System.Xml
Imports System.Xml.Xsl
Public Class PhaseDescription
Private PName As String
Private PicFile As String
Private PDescription As String
Public Property Name() As String
Get
Return PName
End Get
Set(ByVal Value As String)
If Value = "" Then
PName = "NONE"
Else
PName = Value
End If
End Set
End Property
Public Property Description() As String
Get
Return PDescription
End Get
Set(ByVal Value As String)
If Value = "" Then
PDescription = "NONE"
Else
PDescription = Value
End If
End Set
End Property
Public Property ImageFile() As String
Get
If File.Exists(PicFile) = True Then
Return PicFile
Else
Return "NONE"
End If
Return PicFile
End Get
Set(ByVal Value As String)
If Value = "" Then
PicFile = "NONE"
Else
PicFile = Value
End If
End Set
End Property
Public Sub New(ByVal sName As String, _
ByVal sDescription As String, _
ByVal sPictureFile As String)
Name = sName
ImageFile = sPictureFile
Description = sDescription
End Sub
Public Sub New()
Name = "NONE"
Description = "NONE"
ImageFile = "NONE"
End Sub
Public Sub SaveXML(ByVal xtw As XmlTextWriter)
xtw.WriteStartElement("PhaseDescription")
xtw.WriteElementString("Name", Name)
xtw.WriteElementString("ImageFile", ImageFile)
xtw.WriteElementString("Description", Description)
xtw.WriteEndElement()
End Sub
Public Function LoadXML(ByVal xtr As XmlTextReader) As Integer
Dim sTempString As String
Dim ReturnSuccess As Integer = 0
Dim ReturnFailure As Integer = 1
Do While xtr.Read
If xtr.NodeType = XmlNodeType.EndElement Then
If xtr.Name = "PhaseList" Then
Return ReturnFailure
Exit Function
End If
End If
If xtr.NodeType = XmlNodeType.EndElement Then
If xtr.Name = "PhaseDescription" Then
Return ReturnSuccess
Exit Function
End If
End If
If xtr.NodeType = XmlNodeType.Element Then
Select Case xtr.Name
Case "Name"
xtr.Read()
Name = xtr.Value
Case "Description"
xtr.Read()
Description = xtr.Value
Case "ImageFile"
xtr.Read()
ImageFile = xtr.Value
End Select
End If
Loop
Return ReturnFailure
End Function
End Class
assistance.
Basically I have created a class called PhaseDescription. This class
has the following three private members, Name, Description and
ImageFile.
I also have a class called Phases which contains an array of
PhaseDescription objects. There are also additional subroutines in the
class.
Finally in my program I have a public variable called PhaseList that
is defined as follows in my main code module.
Public PhasesList As Phases = New Phases()
I then have a form called frmEditPhase that is used to work with this
variable. When the form loads it populates a combo box on the form
called cmbPhaseName with the names of the objects contained by the
PhasesList variable.
On initial load into the form everything works fine and the objects
contain the correct information that they loaded with. However if I
just strictly manipulate the combo box after loading the form then
after three or four selections I will lose the ImageFile reference.
The ImageFile is a string variable that contains the filename of a jpg
image. The description string however continues to keep it's
information while the ImageFile string gets reset to NONE.
I have a second set of objects that are 99% identical to keep athlete
records. Those two objects work fine! I have even taken those objects
and performed the bare minimum needed to convert them to Phases and
PhaseDescriptions. The problem still existed so I then modified the
selected index code to mirror what's in use in the form Athlete that
works fine.
I have use breaks and watched the progress through the code as well. I
honestly cannot see why I am loosing the reference.
Does anyone have any suggestions on what is going on here. It reminds
me of memory pointer issues in C++ but the fact that the descriptions
are being preserved while the imagefile info in the same object is
being lost has me stumped.
Any suggestions? (Code follows).
~Jamie N
Private Sub frmEditPhase_Load(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles MyBase.Load
Dim iTempCounter As Integer
Dim aSkillNames() As String
cmbPhaseName.Sorted = True
PhasesList.PopulateNamesComboBox(cmbPhaseName)
If PhasesList.NumberPhases > -1 Then
cmbPhaseName.SelectedItem = PhasesList.GetFirstPhaseName
End If
End Sub
Private Sub cmbPhaseName_SelectedIndexChanged(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
cmbPhaseName.SelectedIndexChanged
Dim sImageFileName As String
Dim sLevelName As String
Dim iLoopCounter As Integer
Dim TempPhase As PhaseDescription = New PhaseDescription()
TempPhase = PhasesList.View(cmbPhaseName.SelectedItem)
txtPhaseDescription.Text = TempPhase.Description
If TempPhase.ImageFile = "NONE" Then
picSkillShot.Image = Nothing
Else
picSkillShot.Image = Image.FromFile(TempPhase.ImageFile)
End If
' cmbPhaseName.SelectedItem = TempPhase.Name
TempPhase = Nothing
' CommentsList.PopulateCommentsListBox(cmbPhaseName.SelectedItem,
lstSkillComments)
End Sub
Imports System.Xml
Imports System.Xml.Xsl
Imports System.IO
Public Class Phases
Private PhaseArray(-1) As PhaseDescription
ReadOnly Property NumberPhases() As Integer
' Returns the actual number of comments available in zero
based notation.
' Add one to the answer if you want to think numbers the way
people do.
Get
Return PhaseArray.GetUpperBound(0)
End Get
End Property
Public Sub Add(ByVal TempPhase As PhaseDescription)
Dim iNumPhases As Integer = NumberPhases
iNumPhases += 1
ReDim Preserve PhaseArray(iNumPhases)
PhaseArray(iNumPhases) = New PhaseDescription()
PhaseArray(iNumPhases) = TempPhase
End Sub
Public Sub Delete(ByVal sName As String)
Dim iLoopCounter As Integer
Dim iOrigLastElement As Integer
Dim iFoundComment As Integer = -1
iOrigLastElement = NumberPhases
For iLoopCounter = 0 To iOrigLastElement
If PhaseArray(iLoopCounter).Name.ToUpper = sName.ToUpper
Then
iFoundComment = iLoopCounter
Exit For
End If
Next
If iFoundComment > -1 Then
iOrigLastElement -= 1
For iLoopCounter = iFoundComment To iOrigLastElement
PhaseArray(iLoopCounter) = PhaseArray(iLoopCounter +
1)
Next
ReDim Preserve PhaseArray(iOrigLastElement)
'AthleteArray(iOrigLastElement + 1) = Nothing
End If
End Sub
Public Function GetFirstPhaseName() As String
If NumberPhases > -1 Then
Return PhaseArray(0).Name
Else
Return "NONE"
End If
End Function
Public Sub LoadXML(ByVal sFileName As String)
Dim xtr As New XmlTextReader(sFileName)
Dim iReturnCode As Integer = 0
'Dim TempAthlete As New Athlete()
If File.Exists(sFileName) = True Then
While Not xtr.EOF
Dim TempPhase As PhaseDescription = New
PhaseDescription()
iReturnCode = TempPhase.LoadXML(xtr)
If iReturnCode = 0 Then
Add(TempPhase)
TempPhase = Nothing
End If
End While
'MessageBox.Show(iAthleteCounter & " objects loaded",
"Number of Athlete Objects")
xtr.Close()
xtr = Nothing
End If
End Sub
Public Sub PopulateNamesListBox(ByRef PhasesListbox As ListBox)
Dim iLoopCounter As Integer
PhasesListbox.Items.Clear()
For iLoopCounter = 0 To NumberPhases
PhasesListbox.Items.Add(PhaseArray(iLoopCounter).Name)
Next
End Sub
Public Sub PopulateNamesComboBox(ByRef PhaseComboBox As ComboBox)
Dim iLoopCounter As Integer
PhaseComboBox.Items.Clear()
For iLoopCounter = 0 To NumberPhases
PhaseComboBox.Items.Add(PhaseArray(iLoopCounter).Name)
Next
End Sub
Public Sub SaveXML(ByVal sFileName As String)
Dim xtw As New XmlTextWriter(sFileName,
System.Text.Encoding.UTF8)
Dim iLoopCounter As Integer
xtw.Formatting = Formatting.Indented
xtw.Indentation = 2
xtw.QuoteChar = """"c
xtw.WriteStartDocument(True)
xtw.WriteStartElement("PhaseList")
For iLoopCounter = 0 To NumberPhases
PhaseArray(iLoopCounter).SaveXML(xtw)
Next
xtw.WriteEndElement()
xtw.WriteEndDocument()
xtw.Close()
xtw = Nothing
End Sub
Public Function View(ByVal sName As String) As PhaseDescription
Dim iLoopCounter As Integer
For iLoopCounter = 0 To NumberPhases
If PhaseArray(iLoopCounter).Name.ToUpper = sName.ToUpper
Then
Return PhaseArray(iLoopCounter)
Exit Function
End If
Next
End Function
Public Sub Edit(ByVal TempPhase As PhaseDescription)
Delete(TempPhase.Name)
Add(TempPhase)
End Sub
Public Function PhaseExists(ByVal sName As String) As Boolean
Dim iOrigLastElement As Integer
Dim iLoopCounter As Integer
iOrigLastElement = NumberPhases
For iLoopCounter = 0 To iOrigLastElement
If PhaseArray(iLoopCounter).Name.ToUpper = sName.ToUpper
Then
Return True
End If
Next
Return False
End Function
End Class
Imports System.IO
Imports System.Xml
Imports System.Xml.Xsl
Public Class PhaseDescription
Private PName As String
Private PicFile As String
Private PDescription As String
Public Property Name() As String
Get
Return PName
End Get
Set(ByVal Value As String)
If Value = "" Then
PName = "NONE"
Else
PName = Value
End If
End Set
End Property
Public Property Description() As String
Get
Return PDescription
End Get
Set(ByVal Value As String)
If Value = "" Then
PDescription = "NONE"
Else
PDescription = Value
End If
End Set
End Property
Public Property ImageFile() As String
Get
If File.Exists(PicFile) = True Then
Return PicFile
Else
Return "NONE"
End If
Return PicFile
End Get
Set(ByVal Value As String)
If Value = "" Then
PicFile = "NONE"
Else
PicFile = Value
End If
End Set
End Property
Public Sub New(ByVal sName As String, _
ByVal sDescription As String, _
ByVal sPictureFile As String)
Name = sName
ImageFile = sPictureFile
Description = sDescription
End Sub
Public Sub New()
Name = "NONE"
Description = "NONE"
ImageFile = "NONE"
End Sub
Public Sub SaveXML(ByVal xtw As XmlTextWriter)
xtw.WriteStartElement("PhaseDescription")
xtw.WriteElementString("Name", Name)
xtw.WriteElementString("ImageFile", ImageFile)
xtw.WriteElementString("Description", Description)
xtw.WriteEndElement()
End Sub
Public Function LoadXML(ByVal xtr As XmlTextReader) As Integer
Dim sTempString As String
Dim ReturnSuccess As Integer = 0
Dim ReturnFailure As Integer = 1
Do While xtr.Read
If xtr.NodeType = XmlNodeType.EndElement Then
If xtr.Name = "PhaseList" Then
Return ReturnFailure
Exit Function
End If
End If
If xtr.NodeType = XmlNodeType.EndElement Then
If xtr.Name = "PhaseDescription" Then
Return ReturnSuccess
Exit Function
End If
End If
If xtr.NodeType = XmlNodeType.Element Then
Select Case xtr.Name
Case "Name"
xtr.Read()
Name = xtr.Value
Case "Description"
xtr.Read()
Description = xtr.Value
Case "ImageFile"
xtr.Read()
ImageFile = xtr.Value
End Select
End If
Loop
Return ReturnFailure
End Function
End Class