Serialisierung und Deserialisierung eines Objekts aus einer DLL

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Serialisierung und Deserialisierung eines Objekts aus einer DLL

    Hallo zusammen,

    mein erster Post hier - und das ein Thema, das mich jetzt dann doch schon zur Verzweiflung bringt! :(

    Ich habe 2 VB.net Projekte (beide Windows Forms - Anwendung A und Anwendung B). Mit Anwendung A erstelle ich eine "Objektstruktur" und speichere diese mit binärer serialisierung. Das zweite Projekt (Anwendung B) sollte die so erstellte datei wieder öffnen und dann mit den eingelesenen Objekten weiter arbeiten.

    Da ich jetzt die Klassen nicht 2mal implementieren wollte, habe ich diese in eine DLL ausgelagert. Die dll habe ich nun in beide Projekte eingebunden. Das funktioniert soweit auch. Also sowohl intellisense findet alles, als auch das der restliche Code problemlos läuft.

    Nun aber zum eigentlichen Problem:
    Wenn ich jetzt eine Datei in Anwendung A speichere, dann steht in dem binären File ein Verweis auf diese Anwendung. Versuche ich nun diese Datei in Anwendung B zu öffnen, dann kommt eine System.Reflection.TargetInvocationException. Wenn ich die serialisierte Datei in einem Texteditor öffne finde ich den Verweis auf das andere Projekt auch:

    Quellcode

    1. JNCpoPRO_GripperEdit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null?


    Folgender Fehler kommt beim Einlesen des Streams:
    Exception:

    Quellcode

    1. System.Reflection.TargetInvocationException
    2. {"Ein Aufrufziel hat einen Ausnahmefehler verursacht."}

    InnerException:

    Quellcode

    1. {"Die Datei oder Assembly ""NCpoPRO_GripperEdit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"" oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden.":"NCpoPRO_GripperEdit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"}


    Wobei NCpoPRO_GripperEdit der Projektname der Anwendung A ist...

    Wie kann ich ihm das jetzt abgewöhnen? Ich muss doch die Objekte ohne Verweis auf die speichernde Anwendung ablegen

    Meine Recherchen im Netz sind leider erfolglos geblieben. Daher bitte ich hier um den ein oder anderen hilfreichen Hinweis! :)

    Danke schon mal im Voraus für Eure Unterstützung,

    Günther
    @GuentherA Willkommen im Forum. :thumbup:
    Mit welchem Code serialisierst Du?
    Gugst Du vielleicht mal hier, das sieht dann so aus:

    XML-Quellcode

    1. <?xml version="1.0" encoding="Windows-1252"?>
    2. <MainLanguage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    3. <Language>de-DE</Language>
    4. </MainLanguage>

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    GuentherA schrieb:


    Da ich jetzt die Klassen nicht 2mal implementieren wollte, habe ich diese in eine DLL ausgelagert. Die dll habe ich nun in beide Projekte eingebunden.

    Wenn ich jetzt eine Datei in Anwendung A speichere, dann steht in dem binären File ein Verweis auf diese Anwendung.
    Exception:

    Quellcode

    1. {"Die Datei oder Assembly ""NCpoPRO_GripperEdit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"" oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden.":"NCpoPRO_GripperEdit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"}
    Der Fehler sagt, dass du offensichtlich Klassen aus Anwendung A mit-serialisiert hast.
    Also deine Überlegungen und die Umsetzung scheint mir im Grunde vollkommen korrekt, nur was du dann serialisierst, darf keinerlei Abhängigkeit zu irgendeiner Klasse oder Form oder UserControl haben, die in Anwendung A angelegt ist - ausschliesslich Klassen der ausgelagerten Dll sind zulässig.

    Evtl klärt sich was, wenn du mal deinen (de-)serialisierungs-Code einstellst - ach, das sagte Rod ja auch schon.

    Na das geht ja echt schnell! :) Danke für deine Antwort Rod!

    Serialisiert wird über folgende Klasse:

    Spoiler anzeigen

    Quellcode

    1. Public Class Serializer
    2. Public Shared Sub Serialize(Of T)(ByVal compression As Boolean,
    3. ByVal path As String, ByVal instance As T)
    4. Try
    5. Dim fs As Stream = New FileStream(path, FileMode.OpenOrCreate)
    6. Dim bf As New BinaryFormatter
    7. If compression Then fs = New GZipStream(fs, CompressionMode.Compress)
    8. bf.Serialize(fs, instance)
    9. fs.Close()
    10. Catch ex As Exception
    11. MessageBox.Show(ex.Message, Application.ProductName,
    12. MessageBoxButtons.OK, MessageBoxIcon.Error)
    13. If Not IsNothing(ex.InnerException) Then
    14. MessageBox.Show(ex.InnerException.Message, Application.ProductName,
    15. MessageBoxButtons.OK, MessageBoxIcon.Error)
    16. End If
    17. End Try
    18. End Sub
    19. Public Shared Sub Serialize(Of T)(ByVal path As String, ByVal instance As T)
    20. Serialize(False, path, instance)
    21. End Sub
    22. Public Shared Function DeSerialize(Of T)(ByVal compression As Boolean,
    23. ByVal path As String, ByVal defaultInstance As T) As T
    24. ' Try
    25. If Not File.Exists(path) Then
    26. Return defaultInstance
    27. End If
    28. Dim fs As Stream = New FileStream(path, FileMode.OpenOrCreate)
    29. Dim bf As New BinaryFormatter
    30. If compression Then fs = New GZipStream(fs, CompressionMode.Decompress)
    31. DeSerialize = CType(bf.Deserialize(fs), T)
    32. fs.Close()
    33. 'Catch ex As Exception
    34. ' MessageBox.Show(ex.Message, Application.ProductName,
    35. ' MessageBoxButtons.OK, MessageBoxIcon.Error)
    36. 'End Try
    37. End Function
    38. Public Shared Function DeSerialize(Of T)(ByVal path As String,
    39. ByVal defaultInstance As T) As T
    40. Return DeSerialize(Of T)(False, path, defaultInstance)
    41. End Function
    42. Public Shared Function DeSerialize(Of T As New)(ByVal path As String) As T
    43. Return DeSerialize(Of T)(path, New T)
    44. End Function
    45. Public Shared Function DeSerialize(Of T As New)(
    46. ByVal compression As Boolean, ByVal path As String) As T
    47. Return DeSerialize(Of T)(compression, path, New T)
    48. End Function
    49. End Class



    In der obersten Klasse meiner Struktur gibt es dann noch eine methode Load und Save:

    Spoiler anzeigen

    Quellcode

    1. Public Sub Save(ByVal Pfad As String)
    2. 'Serialize object to a text file.
    3. Dim ser As New Serializer()
    4. Serializer.Serialize(Of Gripper)(Pfad, Me)
    5. End Sub
    6. Public Shared Function Load(dataPath As String) As Gripper
    7. ' Dadurch, dass die Klasse "Sub New()" aufweist, kann die
    8. ' Serializer-Klasse, wenn keine Datei vorhanden ist,
    9. ' eine DefaultInstance zurückgeben.
    10. Return Serializer.DeSerialize(Of Gripper)(dataPath)
    11. End Function



    Dein Link bringt mich damit jetzt noch nicht recht weiter - oder übersehe ich was? :)

    Danke und LG
    Günther

    ErfinderDesRades schrieb:

    Der Fehler sagt, dass du offensichtlich Klassen aus Anwendung A mit-serialisiert hast.


    Jap, nur suche ich mittlerweile seit Stunden zum - auf wienerisch ausgedrückt - wickerl - und hab keine Ahnung wo ich da was mit serialisiere... :(

    Ok, ich wollte es euch eigentlich ersparen, dass ihr da durch den kompletten code der Klassen durch müßt aber es hilft wohl nix... :)

    Hier die Klasse: Gripper
    Spoiler anzeigen

    Quellcode

    1. <Serializable()>
    2. Public Class Gripper
    3. Implements INotifyPropertyChanged
    4. Private m_Node As New TreeNode
    5. Private m_Name As String
    6. Private m_Abmessungen As SizeF
    7. Private m_GripperPosition As PointF
    8. Private m_GroupCount As Integer
    9. Private m_SaugerCount As Integer
    10. Private m_GripperRectanglePosition As PointF
    11. Private m_GreiferRand As SizeF
    12. Private m_isAuswahl As Boolean
    13. Private WithEvents m_SaugerGroups As New BindingList(Of SaugerGroup)
    14. Private Event Name_Changed()
    15. Private Event Node_Changed()
    16. Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    17. ' This method is called by the Set accessor of each property.
    18. ' The CallerMemberName attribute that is applied to the optional propertyName
    19. ' parameter causes the property name of the caller to be substituted as an argument.
    20. Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
    21. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    22. End Sub
    23. <Category("Greifer"), Description("Greifer Benennung"), DisplayName("Name")>
    24. Public Property Name As String
    25. Get
    26. Return m_Name
    27. End Get
    28. Set(value As String)
    29. m_Name = value
    30. m_Node.Text = value
    31. NotifyPropertyChanged()
    32. End Set
    33. End Property
    34. <[ReadOnly](True), Category("Greifer"), Description("Abmessungen des den Greifer umschließenden Rechtecks"), DisplayName("Abmessungen")>
    35. Public Property Abmessungen As SizeF
    36. Get
    37. Return m_Abmessungen
    38. End Get
    39. Set(value As SizeF)
    40. m_Abmessungen = value
    41. NotifyPropertyChanged()
    42. End Set
    43. End Property
    44. <TypeConverter(GetType(PointFConverter)),
    45. [ReadOnly](False), Category("Greifer"), Description("Position des Greifermittelpunkts bezogen auf Tool0"), DisplayName("Position")>
    46. Public Property GripperPosition As PointF
    47. Get
    48. Return m_GripperPosition
    49. End Get
    50. Set(value As PointF)
    51. m_GripperPosition = value
    52. NotifyPropertyChanged()
    53. End Set
    54. End Property
    55. <[Browsable](False)>
    56. Public Property Node As TreeNode
    57. Get
    58. Return m_Node
    59. End Get
    60. Set(value As TreeNode)
    61. m_Node = value
    62. NotifyPropertyChanged()
    63. End Set
    64. End Property
    65. <[ReadOnly](True), Category("Greifer"), Description("Auflistung der Saugergruppen"), DisplayName("Saugergruppen Auflistung")>
    66. Public ReadOnly Property SaugerGroups As BindingList(Of SaugerGroup)
    67. Get
    68. Return m_SaugerGroups
    69. End Get
    70. End Property
    71. <[ReadOnly](True), Category("Greifer"), Description("Anzahl der dem Greifer zugeordneten Gruppen"), DisplayName("Anzahl Gruppen")>
    72. Public ReadOnly Property GroupCount As Integer
    73. Get
    74. Return m_GroupCount
    75. End Get
    76. End Property
    77. <[ReadOnly](True), Category("Greifer"), Description("Anzahl der dem Greifer zugeordneten Sauger"), DisplayName("Anzahl Sauger")>
    78. Public Property SaugerCount As Integer
    79. Get
    80. Return m_SaugerCount
    81. End Get
    82. Set(value As Integer)
    83. m_SaugerCount = value
    84. NotifyPropertyChanged()
    85. End Set
    86. End Property
    87. ''' <summary>
    88. ''' Positioin des den Greifer umschließenden Rechtecks
    89. ''' Angegeben wird der linke- obere Punkt des Rechtecks
    90. ''' </summary>
    91. ''' <returns></returns>
    92. <TypeConverter(GetType(PointFConverter)), [Browsable](False)>
    93. Public Property GripperRectanglePosition As PointF
    94. Get
    95. Return m_GripperRectanglePosition
    96. End Get
    97. Set(value As PointF)
    98. m_GripperRectanglePosition = value
    99. End Set
    100. End Property
    101. ''' <summary>
    102. ''' Positioin des den Greifer umschließenden Rechtecks
    103. ''' Angegeben wird der linke- obere Punkt des Rechtecks
    104. ''' </summary>
    105. ''' <returns></returns>
    106. <[ReadOnly](False), Category("Greifer"), Description("Zur Berücksichtigender Rand zwischen Greiferaußenkante und äußerstem Greifer" & vbCrLf & "Wert > 0!"), DisplayName("Greifer Rand")>
    107. Public Property GreiferRand As SizeF
    108. Get
    109. Return m_GreiferRand
    110. End Get
    111. Set(value As SizeF)
    112. If value.Width = 0 Then
    113. value.Width = 1
    114. ElseIf value.Height = 0 Then
    115. value.Height = 1
    116. End If
    117. m_Abmessungen = m_Abmessungen + value
    118. m_GreiferRand = value
    119. NotifyPropertyChanged()
    120. End Set
    121. End Property
    122. <[Browsable](False)>
    123. Public Property IsAuswahl As Boolean
    124. Get
    125. Return m_isAuswahl
    126. End Get
    127. Set(value As Boolean)
    128. m_isAuswahl = value
    129. End Set
    130. End Property
    131. Public Sub New()
    132. imgList1.Images.Add("Greifer.jpg", My.Resources.Greifer)
    133. imgList1.Images.Add("Sauger.jpg", My.Resources.Sauger)
    134. imgList1.Images.Add("Gruppe.jpg", My.Resources.Gruppe)
    135. m_Node.Name = m_Name
    136. m_Node.ImageKey = "Greifer.jpg"
    137. m_Node.SelectedImageKey = "Greifer.jpg"
    138. m_GreiferRand = New SizeF(40, 40)
    139. End Sub
    140. Public Sub AddSaugerGroup(newSaugerGroup As SaugerGroup)
    141. m_SaugerGroups.Add(newSaugerGroup)
    142. m_Node.Nodes.Add(newSaugerGroup.Node)
    143. m_GroupCount = m_SaugerGroups.Count
    144. End Sub
    145. Public Sub RemoveSauger(SaugerGroup As SaugerGroup)
    146. m_SaugerGroups.Remove(SaugerGroup)
    147. m_Node.Nodes.Remove(SaugerGroup.Node)
    148. m_GroupCount = m_SaugerGroups.Count
    149. End Sub
    150. Public Sub ClearGroups()
    151. m_SaugerGroups.Clear()
    152. m_Node.Nodes.Clear()
    153. m_GroupCount = m_SaugerGroups.Count
    154. End Sub
    155. Private Sub NameHasChanged() Handles Me.Name_Changed
    156. Me.Node.Text = m_Name
    157. End Sub
    158. Private Sub NodeHasChanged() Handles Me.Node_Changed
    159. m_Name = Me.Node.Text
    160. End Sub
    161. Public Sub Save(ByVal Pfad As String)
    162. 'Serialize object to a text file.
    163. Dim ser As New Serializer()
    164. Serializer.Serialize(Of Gripper)(Pfad, Me)
    165. End Sub
    166. Public Shared Function Load(dataPath As String) As Gripper
    167. ' Dadurch, dass die Klasse "Sub New()" aufweist, kann die
    168. ' Serializer-Klasse, wenn keine Datei vorhanden ist,
    169. ' eine DefaultInstance zurückgeben.
    170. Return Serializer.DeSerialize(Of Gripper)(dataPath)
    171. End Function
    172. Private Sub GroupListChanged() Handles m_SaugerGroups.ListChanged
    173. 'sender As Object, e As Object Dim eventArgs
    174. 'MsgBox("Greifer Zeile geändert")
    175. End Sub
    176. End Class

    , SaugerGroup
    Spoiler anzeigen

    Quellcode

    1. <Serializable()>
    2. Public Class SaugerGroup
    3. 'Implements IComponent 'Inherits TypeConverter '(Of PropertySort)
    4. Implements INotifyPropertyChanged
    5. Private m_Name As String
    6. Private m_Abmessungen As SizeF
    7. Private m_GroupPosition As PointF
    8. Private m_SaugerCount As Integer
    9. Private m_Node As New TreeNode
    10. Private m_Parent As Gripper
    11. Private m_isAuswahl As Boolean
    12. Private m_GroupColor As New Color
    13. Private WithEvents m_SaugerList As New BindingList(Of SaugerData)
    14. Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    15. ' This method is called by the Set accessor of each property.
    16. ' The CallerMemberName attribute that is applied to the optional propertyName
    17. ' parameter causes the property name of the caller to be substituted as an argument.
    18. Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
    19. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    20. End Sub
    21. <Category("Greifergruppe"), Description("Informationen zum gesamten Greifer"), DisplayName("Bezeichnung")>
    22. Public Property Name As String
    23. Get
    24. Return m_Name
    25. End Get
    26. Set(value As String)
    27. m_Name = value
    28. m_Node.Text = value
    29. NotifyPropertyChanged()
    30. End Set
    31. End Property
    32. <Category("Greifergruppe"),
    33. Description("Aussenabmessungen der Gruppe in X- Y-Richtung"),
    34. DisplayName("Abmessungen")>
    35. Public Property Abmessungen As SizeF
    36. Get
    37. Return m_Abmessungen
    38. End Get
    39. Set(value As SizeF)
    40. m_Abmessungen = value
    41. NotifyPropertyChanged()
    42. End Set
    43. End Property
    44. ''' <summary>
    45. ''' Positioin des Mittelunktes der Saugergruppe
    46. ''' </summary>
    47. ''' <returns></returns>
    48. <TypeConverter(GetType(PointFConverter)),
    49. Category("Greifergruppe"),
    50. Description("Position der Greifergruppe bezogen auf den Greifermittelpunkt"),
    51. DisplayName("Position")>
    52. Public Property GroupPosition As PointF
    53. Get
    54. Return m_GroupPosition
    55. End Get
    56. Set(value As PointF)
    57. m_GroupPosition = value
    58. NotifyPropertyChanged()
    59. End Set
    60. End Property
    61. <[Browsable](False)>
    62. Public Property Node As TreeNode
    63. Get
    64. Return m_Node
    65. End Get
    66. Set(value As TreeNode)
    67. m_Node = value
    68. NotifyPropertyChanged()
    69. End Set
    70. End Property
    71. Public ReadOnly Property SaugerList As BindingList(Of SaugerData)
    72. Get
    73. Return m_SaugerList
    74. End Get
    75. End Property
    76. Public ReadOnly Property SaugerCount As Integer
    77. Get
    78. Return m_SaugerCount
    79. End Get
    80. End Property
    81. ''' <summary>
    82. '''Farbe der Sauger in der Darstellung
    83. ''' </summary>
    84. ''' <returns></returns>
    85. <[Browsable](True),
    86. Category("Greifergruppe"),
    87. Description("Farbe der Sauger in der Darstellung"),
    88. DisplayName("Gruppenfarbe")>
    89. Public Property GroupColor As Color
    90. Get
    91. Return m_GroupColor
    92. End Get
    93. Set(value As Color)
    94. m_GroupColor = value
    95. For Each sa As SaugerData In SaugerList
    96. sa.SaugerColor = value
    97. Next
    98. End Set
    99. End Property
    100. <[Browsable](True)>
    101. Public Property IsAuswahl As Boolean
    102. Get
    103. Return m_isAuswahl
    104. End Get
    105. Set(value As Boolean)
    106. m_isAuswahl = value
    107. End Set
    108. End Property
    109. Public Sub New()
    110. m_Node.ImageKey = "Gruppe.jpg"
    111. m_Node.SelectedImageKey = "Gruppe.jpg"
    112. Dim r As New Random
    113. m_GroupColor = Color.FromArgb(255, r.Next(0, 256), r.Next(0, 256), r.Next(0, 256))
    114. End Sub
    115. Public Sub AddSauger(Sauger As SaugerData)
    116. SaugerList.Add(Sauger)
    117. SaugerList.Last.LaufendeNr = SaugerList.Count
    118. m_SaugerCount = m_SaugerList.Count
    119. m_Node.Nodes.Add(Sauger.Node)
    120. End Sub
    121. Public Function RemoveSauger(Sauger As SaugerData) As Boolean
    122. Dim ListRemove As Boolean
    123. ListRemove = m_SaugerList.Remove(Sauger)
    124. m_SaugerCount = m_SaugerList.Count
    125. m_Node.Nodes.Remove(Sauger.Node)
    126. If ListRemove Then
    127. Return True
    128. Else
    129. Return False
    130. End If
    131. End Function
    132. Public Sub ClearSauger()
    133. m_SaugerList.Clear()
    134. m_Node.Nodes.Clear()
    135. m_SaugerCount = m_SaugerList.Count ' m_SaugerTable.Rows.Count 'm_SaugerList.Count
    136. End Sub
    137. Private Sub SaugerListChanged() Handles m_SaugerList.ListChanged
    138. 'sender As Object, e As Object Dim eventArgs
    139. 'MsgBox("saugergroup Zeile geändert")
    140. 'Abmessungen der Gruppe anpassen
    141. End Sub
    142. Private Sub SaugerGroup_PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Handles Me.PropertyChanged
    143. ' MsgBox("SaugerGroup_PropertyChanged")
    144. End Sub
    145. End Class


    und SaugerData
    Spoiler anzeigen

    Quellcode

    1. <Serializable()>
    2. Public Class SaugerData
    3. Implements INotifyPropertyChanged
    4. Private m_Type As String
    5. Private m_laufendeNr As String
    6. Private m_DurchmesserGespannt As Single
    7. Private m_DurchmesserEntspannt As Single
    8. Private m_DurchmesserBohrung As Single
    9. Private m_Hoehe As Single
    10. Private m_zHub As Single
    11. Private m_Saugkraft As Single
    12. Private m_AbreissKraft As Single
    13. Private m_Querkraft As Single
    14. Private m_QuerkraftGeoelt As Single
    15. Private m_Volumen As Single
    16. Private m_WerkstueckRmin As Single
    17. Private m_EmpfSchlauch As Single
    18. Private m_isActive As Boolean
    19. Private m_isComplete As Boolean
    20. Private m_Node As New TreeNode
    21. Private m_SaugerPosition As New PointF
    22. Private m_isAuswahl As Boolean
    23. Private m_State As SaugerState
    24. 'Farben
    25. Private m_SaugerColor As New Color
    26. 'Strichstärke
    27. Private m_SaugerPenWidth As Integer
    28. Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    29. ' This method is called by the Set accessor of each property.
    30. ' The CallerMemberName attribute that is applied to the optional propertyName
    31. ' parameter causes the property name of the caller to be substituted as an argument.
    32. Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
    33. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    34. End Sub
    35. 'Private m_TableRow As DataRow
    36. <[ReadOnly](True), Category("Sauger"),
    37. Description("Saugertypenbezeichnung lt. Katalog" & vbCrLf & "Read Only!"),
    38. DisplayName("Type")>
    39. Public Property Type As String
    40. Get
    41. Return m_Type
    42. End Get
    43. Set(value As String)
    44. m_Type = value
    45. End Set
    46. End Property
    47. <[ReadOnly](True), Category(" Abmessungen"),
    48. Description("Außendurchmesser des Saugers im angesaugtem Zustand"),
    49. DisplayName("D Außen gespannt [mm]" & vbCrLf & "Read Only!")>
    50. Public Property DaussenAngesaugt As Single
    51. Get
    52. Return m_DurchmesserGespannt
    53. End Get
    54. Set(value As Single)
    55. m_DurchmesserGespannt = value
    56. End Set
    57. End Property
    58. <[ReadOnly](True), Category(" Abmessungen"),
    59. DisplayName("D Außen entspannt [mm]"),
    60. Description("Außendurchmesser des Saugers im nicht angesaugtem Zustand" & vbCrLf & "Read Only!")>
    61. Public Property dAussenEntspannt As Single
    62. Get
    63. Return m_DurchmesserEntspannt
    64. End Get
    65. Set(value As Single)
    66. m_DurchmesserEntspannt = value
    67. End Set
    68. End Property
    69. <[ReadOnly](True), Category(" Abmessungen"),
    70. DisplayName("D Bohrung [mm]"),
    71. Description("Durchmesser der Bohrung, durch welche das Vakuum eingebracht wird" & vbCrLf & "Read Only!")>
    72. Public Property DurchmesserBohrung As Single
    73. Get
    74. Return m_DurchmesserBohrung
    75. End Get
    76. Set(value As Single)
    77. m_DurchmesserBohrung = value
    78. End Set
    79. End Property
    80. <[ReadOnly](True), Category(" Abmessungen"),
    81. Description("Höhe des Saugers (ohne Ventil)" & vbCrLf & "Read Only!"),
    82. DisplayName("Höhe [mm]")>
    83. Public Property Hoehe As Single
    84. Get
    85. Return m_Hoehe
    86. End Get
    87. Set(value As Single)
    88. m_Hoehe = value
    89. End Set
    90. End Property
    91. <[ReadOnly](True), Category(" Abmessungen"),
    92. Description("Hub des Saugers beim Ansaugen in Z-Richtung" & vbCrLf & "Read Only!"),
    93. DisplayName("Z-Hub [mm]")>
    94. Public Property zHub As Single
    95. Get
    96. Return m_zHub
    97. End Get
    98. Set(value As Single)
    99. m_zHub = value
    100. End Set
    101. End Property
    102. <[ReadOnly](True), Category(" Abmessungen"),
    103. Description("Empfohlener Schlauchdurchmesser lt. Datenblatt" & vbCrLf & "Read Only!"),
    104. DisplayName("empf. Schlauch D [mm]")>
    105. Public Property EmpfSchlauch As Single
    106. Get
    107. Return m_EmpfSchlauch
    108. End Get
    109. Set(value As Single)
    110. m_EmpfSchlauch = value
    111. End Set
    112. End Property
    113. <[ReadOnly](True), Category(" Saug- Eigenschaften"),
    114. Description("Saugkraft laut Datenblatt" & vbCrLf & "Read Only!"),
    115. DisplayName("Saugkraft [N]")>
    116. Public Property Saugkraft As Single
    117. Get
    118. Return m_Saugkraft
    119. End Get
    120. Set(value As Single)
    121. m_Saugkraft = value
    122. End Set
    123. End Property
    124. <[ReadOnly](True), Category(" Saug- Eigenschaften"),
    125. Description("Abreisskraft laut Datenblatt" & vbCrLf & "Read Only!"),
    126. DisplayName("Abreisskraft [N]")>
    127. Public Property AbreissKraft As Single
    128. Get
    129. Return m_AbreissKraft
    130. End Get
    131. Set(value As Single)
    132. m_AbreissKraft = value
    133. End Set
    134. End Property
    135. <[ReadOnly](True), Category(" Saug- Eigenschaften"),
    136. Description("Querkraft laut Datenblatt" & vbCrLf & "Read Only!"),
    137. DisplayName("Querkraft Kraft [N]")>
    138. Public Property Querkraft As Single
    139. Get
    140. Return m_Querkraft
    141. End Get
    142. Set(value As Single)
    143. m_Querkraft = value
    144. End Set
    145. End Property
    146. <[ReadOnly](True), Category(" Saug- Eigenschaften"),
    147. Description("Querkraft auf geölten Oberflächen laut Datenblatt" & vbCrLf & "Read Only!"),
    148. DisplayName("Querkraft Kraft geölt [N]")>
    149. Public Property QuerkraftGeoelt As Single
    150. Get
    151. Return m_QuerkraftGeoelt
    152. End Get
    153. Set(value As Single)
    154. m_QuerkraftGeoelt = value
    155. End Set
    156. End Property
    157. <[ReadOnly](True), Category(" Abmessungen"),
    158. Description("Volumen laut Datenblatt" & vbCrLf & "Read Only!"),
    159. DisplayName("Volumen [cm³]")>
    160. Public Property Volumen As Single
    161. Get
    162. Return m_Volumen
    163. End Get
    164. Set(value As Single)
    165. m_Volumen = value
    166. End Set
    167. End Property
    168. <[ReadOnly](True), Category(" Abmessungen"),
    169. Description("Min. Werkstückradius" & vbCrLf & "Read Only!"),
    170. DisplayName("Min. Werkstückradius (konvex) [cm³]")>
    171. Public Property WerkstueckRmin As Single
    172. Get
    173. Return m_WerkstueckRmin
    174. End Get
    175. Set(value As Single)
    176. m_WerkstueckRmin = value
    177. End Set
    178. End Property
    179. <[Browsable](False)>
    180. Public Property IsActive As Boolean
    181. Get
    182. Return m_isActive
    183. End Get
    184. Set(value As Boolean)
    185. m_isActive = value
    186. End Set
    187. End Property
    188. <[Browsable](False)>
    189. Public ReadOnly Property IsComplete As Boolean
    190. Get
    191. Return m_isComplete
    192. End Get
    193. End Property
    194. <[Browsable](False)>
    195. Public Property Node As TreeNode
    196. Get
    197. Return m_Node
    198. End Get
    199. Set(value As TreeNode)
    200. m_Node = value
    201. End Set
    202. End Property
    203. <[ReadOnly](True), Category("Sauger"),
    204. Description("Saugernummer in der zugeordneten Gruppe" & vbCrLf & "Read Only!"),
    205. DisplayName("Nummer")>
    206. Public Property LaufendeNr As String
    207. Get
    208. Return m_laufendeNr
    209. End Get
    210. Set(value As String)
    211. m_laufendeNr = value
    212. End Set
    213. End Property
    214. <TypeConverter(GetType(PointFConverter)),
    215. [ReadOnly](False), Category("Sauger"),
    216. Description("Saugerposition in Bezug auf den Mittelpunkt der übergeordneten Gruppe"),
    217. DisplayName("Position")>
    218. Public Property SaugerPosition As PointF
    219. Get
    220. Return m_SaugerPosition
    221. End Get
    222. Set(value As PointF)
    223. m_SaugerPosition = value
    224. NotifyPropertyChanged()
    225. End Set
    226. End Property
    227. <[Browsable](True)>
    228. Public Property State As SaugerState
    229. Get
    230. Return m_State
    231. End Get
    232. Set(value As SaugerState)
    233. m_State = value
    234. End Set
    235. End Property
    236. <[Browsable](False), Category("Sauger"),
    237. Description("Saugerfarbe in der Darstellung" & vbCrLf & "Read Only!"),
    238. DisplayName("Saugerfarbe")>
    239. Public Property SaugerColor As Color
    240. Get
    241. Return m_SaugerColor
    242. End Get
    243. Set(value As Color)
    244. m_SaugerColor = value
    245. End Set
    246. End Property
    247. <[Browsable](False)>
    248. Public Property SaugerPenWidth As Integer
    249. Get
    250. Return m_SaugerPenWidth
    251. End Get
    252. Set(value As Integer)
    253. m_SaugerPenWidth = value
    254. End Set
    255. End Property
    256. <[Browsable](False)>
    257. Public Property IsAuswahl As Boolean
    258. Get
    259. Return m_isAuswahl
    260. End Get
    261. Set(value As Boolean)
    262. m_isAuswahl = value
    263. End Set
    264. End Property
    265. Public Sub New()
    266. End Sub
    267. Public Sub New(isActive As Boolean, Sauger_Type As String, Sauger_DurchmesserGespannt As Single, Sauger_DurchmesserEntspannt As Single, Sauger_DurchmesserBohrung As Single, Sauger_Hoehe As Single,
    268. Sauger_zHub As Single, Sauger_Saugkraft As Single, Sauger_AbreissKraft As Single, Sauger_Querkraft As Single, Sauger_QuerkraftGeoelt As Single,
    269. Sauger_Volumen As Single, Sauger_WerkstueckRmin As Single, Sauger_EmpfSchlauch As Integer, parent As SaugerGroup)
    270. m_isActive = isActive
    271. m_Type = Sauger_Type
    272. m_DurchmesserGespannt = Sauger_DurchmesserGespannt
    273. m_DurchmesserEntspannt = Sauger_DurchmesserEntspannt
    274. m_DurchmesserBohrung = DurchmesserBohrung
    275. m_Hoehe = Sauger_Hoehe
    276. m_zHub = Sauger_zHub
    277. m_Saugkraft = Sauger_Saugkraft
    278. m_AbreissKraft = Sauger_AbreissKraft
    279. m_Querkraft = Sauger_Querkraft
    280. m_QuerkraftGeoelt = Sauger_QuerkraftGeoelt
    281. m_Volumen = Sauger_Volumen
    282. m_WerkstueckRmin = Sauger_WerkstueckRmin
    283. m_EmpfSchlauch = Sauger_EmpfSchlauch
    284. m_isComplete = True
    285. m_Node.Text = m_Type
    286. m_Node.ImageKey = "Sauger.jpg"
    287. m_Node.SelectedImageKey = "Sauger.jpg"
    288. MsgBox("DataRow wurde im SaugerData nicht erstellt! Code Einfügen")
    289. End Sub
    290. Public Sub New(datRow As DataRow, dbTable As DataTable)
    291. Dim ColName As String
    292. Dim ColVal As Object
    293. Dim ValType As Type
    294. Dim isNotComplete As Boolean = False
    295. Dim pInfos As Reflection.PropertyInfo() = Me.GetType.GetProperties((Reflection.BindingFlags.GetProperty Or (Reflection.BindingFlags.Public Or Reflection.BindingFlags.Instance)))
    296. Dim pInfo As Reflection.PropertyInfo
    297. For Each col As DataColumn In dbTable.Columns
    298. 'Methodennamen auslesen
    299. ColName = TryCast(col.ColumnName, String)
    300. 'Datentyp der Methode
    301. pInfo = pInfos.Where(Function(x) x.Name = ColName).First
    302. ValType = pInfo.PropertyType
    303. ColVal = Nothing
    304. Select Case ValType.Name
    305. Case "String"
    306. ColVal = TryCast(datRow(ColName), String)
    307. Case "Boolean"
    308. Boolean.TryParse(datRow(ColName), ColVal)
    309. Case "Single"
    310. Single.TryParse(datRow(ColName), ColVal)
    311. End Select
    312. If Not (ColName = Nothing And ColVal = Nothing) Then
    313. 'CallByName(Me, col.ColumnName, CallType.Set, datRow(col))
    314. CallByName(Me, ColName, CallType.Set, ColVal)
    315. Else
    316. isNotComplete = True
    317. End If
    318. Next
    319. m_Node.Text = m_Type
    320. m_Node.ImageKey = "Sauger.jpg"
    321. m_Node.SelectedImageKey = "Sauger.jpg"
    322. 'Objekt in den Tag schreiben, möglicherweise klonen?!
    323. m_Node.Tag = Me
    324. If Not isNotComplete Then m_isComplete = True
    325. End Sub
    326. End Class


    Danke und LG
    @GuentherA Teste mal dieses absolut simple Beispiel, hier mit XML-Serialisierung:
    Serialisierer

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Xml.Serialization
    3. Imports System.Text
    4. Public Class MainLanguage
    5. Public Property Language() As String
    6. Get
    7. Return m_Language
    8. End Get
    9. Set(value As String)
    10. m_Language = value
    11. End Set
    12. End Property
    13. Private m_Language As String
    14. Public Sub New()
    15. Me.Language = ""
    16. End Sub
    17. End Class
    18. NotInheritable Class LanguageSerialization
    19. Private Sub New()
    20. End Sub
    21. Public Shared Sub Save(language As MainLanguage)
    22. Dim file As String = "c:\temp\lang.xml"
    23. Dim fi As New FileInfo(file)
    24. fi.Directory.Create()
    25. ' Serialize object to a XML file.
    26. Using sw As New StreamWriter(file, False, Encoding.[Default])
    27. Dim x As New XmlSerializer(language.[GetType]())
    28. x.Serialize(sw, language)
    29. End Using
    30. End Sub
    31. Public Shared Function Load() As MainLanguage
    32. Dim language = New MainLanguage()
    33. Try
    34. Dim file As String = "c:\temp\lang.xml"
    35. ' Deserialize XML file to a new object.
    36. Using sr As New StreamReader(file, Encoding.[Default])
    37. Dim x As New XmlSerializer(language.[GetType]())
    38. language = DirectCast(x.Deserialize(sr), MainLanguage)
    39. End Using
    40. Catch
    41. ' nix tun, die Settings-Instanz ist nicht valid
    42. End Try
    43. Return language
    44. End Function
    45. End Class
    Aufruf

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim lang = New MainLanguage()
    3. lang.Language = "de-DE"
    4. LanguageSerialization.Save(lang)
    5. End Sub
    6. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    7. Dim lang = LanguageSerialization.Load()
    8. MessageBox.Show(lang.Language)
    9. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    //EDIT:
    Den Smilie kann ich garnicht so oft wiederholen wie ich gern würde!!!! :thumbsup:

    Die Public Events warens! Jetzt klappts!

    1000 Dank an den ErfinderDesRades :)
    Und natürlich auch ein riesen Dankeschön an alle anderen die mich da unterstützt haben!

    Danke und bis bald :)
    LG
    Günther

    ErfinderDesRades schrieb:

    Ah - Objekte mit Events kann man nicht serialisieren.
    Wenn da ein irgendwo in einer Klasse das PropertyChangedEvent abonniert ist, dann hinterlässt das einen Eintrag im Gripper, der dann mit-serialisiert zu werden versucht.

    die Events also mit <NonSerialized> attributieren.


    Aha.... Betrifft das in meinem speziellen Fall die Events die ich definiert habe, also zb. in der Klasse Gripper das PropertyChanged, oder auch die BindingList die ich mit mit WithEvents initialisiere? Das wäre nämlich blöd. Der Inhalt muss nämlich serialisiert werden.

    Riesen Danke auf jeden Fall schon mal - kommen der Sache offensichtlich näher! :)

    LG Gü

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „GuentherA“ ()