It appears you have not yet registered with DEVPPL. To register please click here... (it's fast, easy and free!)

Forum

Log In Sponsors
Board index Programming XML Forum

RESOLVED Cannotdeserializeanarrayofobjects(ofvariabletype)

RESOLVED Cannotdeserializeanarrayofobjects(ofvariabletype)

Postby moripi on Tue May 03, 2011 4:53 pm

Hi helpful folks and gurus

Hey folks, I'm programming an application in Visual Studio 2010, namely in VB.net. I have been developing an application which uses a derived class inherited from TreeView, with the aim of putting custom objects on the nodes. The method I have been using is to have a variable array against the node (of type object) which contains variables in custom classes to contain each of the variables associated with the node.

The two problems I had to overcome were, how to serialize a TreeView, and how to serialize an array of objects (of variable type). Good thing is I overcame both of these with some work of some other folks (and 3 days of my own work).

TreeView: http://www.codeproject.com/KB/vb/TreeVi ... play=Print

Object Array (NOT of variable type). adapted to variable type: http://www.codeproject.com/KB/XML/xmlse ... known.aspx

Serialization works a charm.. Deserialization naddah.. Can find no sufficent documentation for me to debug and work on manual deserialization (of only one variable, the variable array of objects). All others are handled by the regular deserializer.

Effectively the xmlserializerforunknown URL provided a solution which manually handles both the type handling and the handling of the object array.

The main error I'm having lies in the ReadXml, function. I just can't align the xml with the code.

Here is the Code and the XML. (see earlier URLs for the inline which have been edited out for brevity)

If someone can assist with the ReadXml to process the XML or even tell me how to do it without using custom Serialization (please please i'm sure its possible!!)

Thanks in advance folks. Its a tough one.

Brian

Code: Select all
Imports System.Xml.Serialization
Imports System.Xml

Public Class TreeViewDataAccess
  <Serializable()> Public Structure TreeViewData
    Public Nodes() As TreeNodeData
    Public Sub New(ByVal treeview As BE.TreeModified)
      If treeview.Nodes.Count = 0 Then Exit Sub
      ReDim Nodes(treeview.Nodes.Count - 1)
      For i As Integer = 0 To treeview.Nodes.Count - 1
      Nodes(i) = New TreeNodeData(treeview.Nodes(i))
      Next
    End Sub
    Public Sub PopulateTree(ByVal treeview As BE.TreeModified)
      If Me.Nodes Is Nothing OrElse Me.Nodes.Length = 0 Then Exit Sub
      treeview.BeginUpdate()
      For i As Integer = 0 To Me.Nodes.Length - 1
      treeview.Nodes.Add(Me.Nodes(i).ToTreeNode)
      Next
      treeview.EndUpdate()
    End Sub
  End Structure
  Public Class RowCollection
    Implements IXmlSerializable
    <XmlIgnore()> Private _Row As Object()
    <XmlIgnore()> Public Property Row As Object()
      Get
        Return _Row
      End Get
      Set(ByVal value As Object())
        _Row = value
      End Set
    End Property
    Public Sub New(ByVal RowsOriginal As Object())
      Row = RowsOriginal
    End Sub
    Public Sub New()
    End Sub
    Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements System.Xml.Serialization.IXmlSerializable.GetSchema
      GetSchema = Nothing
    End Function
    Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml
      reader.ReadStartElement("NodeRowsPublic")
      reader.MoveToContent()
      Dim count As Integer = CInt(reader.GetAttribute("count"))
      reader.ReadStartElement("SavedRows")
      ReDim Preserve Row(count)
      For i As Integer = 0 To count - 1
        Dim xRoot As XmlRootAttribute = New XmlRootAttribute("Row")
        reader.MoveToContent()
        Dim X As XmlReader = reader.ReadSubtree()
        Dim DerivedType As Type = Type.GetType(reader.GetAttribute("type"))
        Row(i) = Activator.CreateInstance(DerivedType)
        Row(i) = New XmlSerializer(DerivedType, xRoot).Deserialize(X)
      Next
      reader.ReadEndElement()
      reader.ReadEndElement()
    End Sub
    Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) Implements System.Xml.Serialization.IXmlSerializable.WriteXml
      writer.WriteStartElement("SavedRows")
      If (Row Is Nothing) Then
        writer.WriteAttributeString("count", 0)
      Else
        Dim RowCount As Integer = 0
        For i As Integer = 0 To Row.GetUpperBound(0)
          If Not (Row(i) Is Nothing) Then
          RowCount += 1
          End If
        Next
        writer.WriteAttributeString("count", RowCount)
        For i As Integer = 0 To Row.GetUpperBound(0)
          If Not (Row(i) Is Nothing) Then
          writer.WriteStartElement("Row")
          writer.WriteAttributeString("type", Row(i).GetType().ToString())
          Dim X As New XmlSerializer(Row(i).GetType())
          X.Serialize(writer, Row(i))
          writer.WriteEndElement()
          End If
        Next
      End If
      writer.WriteEndElement()
    End Sub
  End Class

  <Serializable()> Public Structure TreeNodeData
    Public Text As String
    Public NodeType As String
    Public NodeRowsPublic As RowCollection
    Public ImageIndex As Integer
    Public SelectedImageIndex As Integer
    Public Checked As Boolean
    Public Expanded As Boolean
    Public Tag As Object
    Public Nodes() As TreeNodeData

    Public Sub New(ByVal node As Object)
      Dim NType As Type = node.GetType
      Me.NodeType = node.GetType.ToString
      Me.Text = CTypeDynamic(node, NType).Text
      Me.ImageIndex = CTypeDynamic(node, NType).ImageIndex
      Me.SelectedImageIndex = CTypeDynamic(node, NType).SelectedImageIndex
      Me.Checked = CTypeDynamic(node, NType).Checked
      Me.Expanded = CTypeDynamic(node, NType).IsExpanded
      Me.NodeRowsPublic = New RowCollection(CTypeDynamic(node, NType).SavedValues)
      If (Not node.Tag Is Nothing) AndAlso node.Tag.GetType.IsSerializable Then Me.Tag = node.Tag
      If node.Nodes.Count = 0 Then Exit Sub
      ReDim Nodes(node.Nodes.Count - 1)
      For i As Integer = 0 To node.Nodes.Count - 1
      Nodes(i) = New TreeNodeData(node.Nodes(i))
      Next
    End Sub

    Public Function ToTreeNode() As Object
      Dim NType As Type
      NType = Type.GetType(Me.NodeType)
      ToTreeNode = Activator.CreateInstance(NType)
      ToTreeNode.Text = Me.Text
      ToTreeNode.SavedValues = Me.NodeRowsPublic.Row
      ToTreeNode.ImageIndex = Me.ImageIndex
      ToTreeNode.SelectedImageIndex = Me.SelectedImageIndex
      ToTreeNode.Checked = Me.Checked
      ToTreeNode.Tag = Me.Tag
      If Me.Expanded Then ToTreeNode.Expand()
      If Me.Nodes Is Nothing OrElse Me.Nodes.Length = 0 Then Exit Function
      For i As Integer = 0 To Me.Nodes.Length - 1
        ToTreeNode.Nodes.Add(Me.Nodes(i).ToTreeNode)
      Next
    End Function
  End Structure

  Public Shared Sub LoadTreeViewData(ByVal treeView As BE.TreeModified, ByVal path As String)
    Dim ser As New System.Xml.Serialization.XmlSerializer(GetType(TreeViewData))
    Dim file As New System.IO.FileStream(path, IO.FileMode.Open)
    Dim reader As New System.Xml.XmlTextReader(file)
    Dim treeData As TreeViewData = CType(ser.Deserialize(reader), TreeViewData)
    treeData.PopulateTree(treeView)
    reader.Close()
    file.Close()
    file = Nothing
  End Sub

  Public Shared Sub SaveTreeViewData(ByVal treeView As BE.TreeModified, ByVal path As String)
    Dim ser As New System.Xml.Serialization.XmlSerializer(GetType(TreeViewData))
    Dim file As New System.IO.FileStream(path, IO.FileMode.Create)
    Dim writer As New System.Xml.XmlTextWriter(file, Nothing)
    ser.Serialize(writer, New TreeViewData(treeView))
    writer.Close()
    file.Close()
    file = Nothing
  End Sub
End Class


XML:

Code: Select all
<?xml version="1.0"?>
<TreeViewData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Nodes>
      <TreeNodeData>
         <Text>Thread</Text>
         <NodeType>Financial_Alchemy.BE.NThread</NodeType>
         <NodeRowsPublic>
            <SavedRows count="1">
               <Row type="Financial_Alchemy.Row_Parameter_CheckBox">
                  <Row_Parameter_CheckBox>
                     <ElementCategory>Thread Properties</ElementCategory>
                     <ElementProperty>Enabled</ElementProperty>
                     <ElementSecurity>
                        <Deletable>false</Deletable>
                        <Movable>false</Movable>
                        <CategoryReadOnly>true</CategoryReadOnly>
                        <PropertyReadOnly>true</PropertyReadOnly>
                        <NumberOfAllowableRows>1</NumberOfAllowableRows>
                     </ElementSecurity>
                     <ElementUnits>Boolean</ElementUnits>
                     <ElementBoolean>false</ElementBoolean>
                  </Row_Parameter_CheckBox>
               </Row>
            </SavedRows>
         </NodeRowsPublic>
         <ImageIndex>-1</ImageIndex>
         <SelectedImageIndex>-1</SelectedImageIndex>
         <Checked>false</Checked>
         <Expanded>true</Expanded>
         <Nodes>
            <TreeNodeData>
               <Text>Create Model</Text>
               <NodeType>Financial_Alchemy.BE.NModelOInit</NodeType>
               <NodeRowsPublic>
                  <SavedRows count="2">
                     <Row type="Financial_Alchemy.Row_Parameter_Combo">
                        <Row_Parameter_Combo>
                           <ElementCategory>Model Details</ElementCategory>
                           <ElementProperty>Training Purpose</ElementProperty>
                           <ElementSecurity>
                              <Deletable>true</Deletable>
                              <Movable>true</Movable>
                              <CategoryReadOnly>false</CategoryReadOnly>
                              <PropertyReadOnly>false</PropertyReadOnly>
                              <NumberOfAllowableRows>1</NumberOfAllowableRows>
                           </ElementSecurity>
                           <ElementUnits>Purpose</ElementUnits>
                           <ElementComboItems>
                              <string>Signal Fitness</string>
                              <string>Correlation to Optimal Signal</string>
                              <string>Reduction of Error</string>
                           </ElementComboItems>
                           <ElementComboSelectedItem>Reduction of Error</ElementComboSelectedItem>
                        </Row_Parameter_Combo>
                     </Row>
                     <Row type="Financial_Alchemy.Row_Parameter_Static">
                        <Row_Parameter_Static>
                           <ElementCategory>Optimal Signal</ElementCategory>
                           <ElementProperty>Minimum profit per trade</ElementProperty>
                           <ElementSecurity>
                              <Deletable>true</Deletable>
                              <Movable>true</Movable>
                              <CategoryReadOnly>false</CategoryReadOnly>
                              <PropertyReadOnly>false</PropertyReadOnly>
                              <NumberOfAllowableRows>1</NumberOfAllowableRows>
                           </ElementSecurity>
                           <ElementUnits>Percent</ElementUnits>
                           <ElementValue>
                              <ValueValue>5</ValueValue>
                              <ValueMinimum>0.0001</ValueMinimum>
                              <ValueMaximum>100</ValueMaximum>
                              <ValueIncrement>0.0001</ValueIncrement>
                           </ElementValue>
                        </Row_Parameter_Static>
                     </Row>
                  </SavedRows>
               </NodeRowsPublic>
               <ImageIndex>-1</ImageIndex>
               <SelectedImageIndex>-1</SelectedImageIndex>
               <Checked>false</Checked>
               <Expanded>true</Expanded>
               <Nodes>
               </Nodes>
            </TreeNodeData>
         </Nodes>
      </TreeNodeData>
   </Nodes>
</TreeViewData>
Last edited by moripi on Thu May 19, 2011 6:01 am, edited 1 time in total.
moripi
 
Posts: 5
Joined: Tue May 03, 2011 4:22 pm

Re: Cannot deserialize an array of objects (of variable type)

Postby moripi on Sun May 08, 2011 11:21 pm

bump
moripi
 
Posts: 5
Joined: Tue May 03, 2011 4:22 pm

Re: Cannot deserialize an array of objects (of variable type)

Postby moripi on Sat May 14, 2011 8:31 pm

bump
moripi
 
Posts: 5
Joined: Tue May 03, 2011 4:22 pm

Re: Cannot deserialize an array of objects (of variable type)

Postby moripi on Wed May 18, 2011 2:56 am

bump
moripi
 
Posts: 5
Joined: Tue May 03, 2011 4:22 pm

[RESOLVED] Cannot deserialize an array of objects

Postby moripi on Thu May 19, 2011 5:58 am

RESOLVED

Code: Select all
        Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml
            reader.ReadStartElement("NodeRowsPublic")
            reader.MoveToContent()
            Dim count As Integer = CInt(reader.GetAttribute("count"))
            reader.ReadStartElement("SavedRows")
            reader.MoveToContent()
            ReDim Preserve Row(count - 1)
            For i As Integer = 0 To Row.GetUpperBound(0)
                Dim RowType As Type = Type.GetType(reader.GetAttribute("type"))
                Row(i) = Activator.CreateInstance(RowType)
                reader.ReadStartElement("Row")
                reader.MoveToContent()
                Dim RowText As String = reader.ReadSubtree.ReadOuterXml
                Dim RowNode As XmlReader = reader.ReadSubtree
                'Dim X As XmlReader = reader.ReadSubtree()
                Row(i) = New XmlSerializer(RowType).Deserialize(RowNode)
                reader.ReadEndElement()
                reader.MoveToContent()
                reader.ReadEndElement()
                reader.MoveToContent()
                '                reader.MoveToContent()
                'reader.ReadEndElement()
            Next
            If count <> 0 Then
                reader.ReadEndElement()
            End If
            reader.MoveToContent()
            reader.ReadEndElement()
            reader.MoveToContent()
            'reader.ReadEndElement()
        End Sub



Umm yeah thanks.. for your help...
Last edited by iDad on Thu May 19, 2011 1:08 pm, edited 1 time in total.
Reason: "RESOLVED"
moripi
 
Posts: 5
Joined: Tue May 03, 2011 4:22 pm


Who is online

Users browsing this forum: No registered users and 0 guests