Liste mit Structuren bearbeiten

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

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

    Liste mit Structuren bearbeiten

    Hallo zusammen,

    ich versuche schon die ganze Zeit zu verstehen wieso ich eine Liste mit Structuren, die nachträglich bearbeitet werden sollen nicht so funktionieren wie ich will.

    Hier einmal die Structur :

    VB.NET-Quellcode

    1. Private Structure TmpOrdner
    2. Private mName As String
    3. Private mNameItems As List(Of String)
    4. Private ReadOnly mMainDir As String
    5. Private onElements As List(Of String)
    6. Public Sub New(ByVal NameItems As List(Of String), ByVal MainDir As String)
    7. mNameItems = NameItems
    8. mMainDir = MainDir
    9. onElements = New List(Of String)
    10. End Sub
    11. Public Sub New(ByVal NameItems As List(Of String), ByVal MainDir As String, ByVal Name As String)
    12. mName = Name
    13. mNameItems = NameItems
    14. mMainDir = MainDir
    15. onElements = New List(Of String)
    16. End Sub
    17. Public Property GetName() As String
    18. Get
    19. Return mName
    20. End Get
    21. Set(value As String)
    22. mName = value
    23. End Set
    24. End Property
    25. Public Property GetNameItems() As List(Of String)
    26. Get
    27. Return mNameItems
    28. End Get
    29. Set(value As List(Of String))
    30. mNameItems = value
    31. End Set
    32. End Property
    33. Public ReadOnly Property getMainDir() As String
    34. Get
    35. Return mMainDir
    36. End Get
    37. End Property
    38. Public Property SetElementList() As List(Of String)
    39. Get
    40. Return onElements
    41. End Get
    42. Set(value As List(Of String))
    43. onElements = value
    44. End Set
    45. End Property
    46. End Structure


    Einmal in der Klasse steht ganz oben global :

    VB.NET-Quellcode

    1. Private mtmpOrdner As New List(Of TmpOrdner)


    Wenn ich jetzt mit einem Button :

    VB.NET-Quellcode

    1. For Each mt As TmpOrdner In mtmpOrdner
    2. If mt.GetName = orginalSelectetFolder Then
    3. mt.GetName = TextBox6.Text
    4. orginalSelectetFolder = TextBox6.Text
    5. End If
    6. Next


    die Daten bearbeiten will, wird laut Einzelschritt das Element mt ordentlich mit dem Text aus der Textbox6 beschrieben.

    Wenn ich aber in einer anderen Prozedur die Liste lese, und in z.B. ein Treeview zeichne steht immer noch der Orginale Text.

    Ich denke in die Richtung, dass es mit den Eigenschaften der Structur zusammenhängt? Benutze sonst fast nur Klassen.

    LG
    @Farliam Poste mal den Code, wo die List mit den Strulturen belegt und abgefragt wird.
    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!
    Hey,

    ich habe jetzt einfach mal die "Private Structure" durch "Private Class" und natürlich End Class getauscht. Ergebniss -> Funktioniert

    Also ist das eine Eigenart der Structur die ich nicht kenne?

    Willst du den Code wirklich sehen? Ist eine einzelne Sub die über 200 Zeilen Code-Salat enthält^^

    Sub die die Listbox füllt :

    Spoiler anzeigen

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' <code>Erstellt eine erste Übersicht der Datei, und speichert die Variabeln gloabal</code>
    3. ''' </summary>
    4. ''' <param name="sPfad">Pfad zur Excel Datei</param>
    5. Private Sub CreateFirst(ByVal sPfad As String)
    6. If mPfad = String.Empty Then
    7. MsgBox("Bitte geben Sie erst einen Hauptordner an!", MsgBoxStyle.Exclamation, "Fehlendes Argument")
    8. Exit Sub
    9. End If
    10. 'Gloable Liste leeren
    11. mtmpOrdner.Clear()
    12. TreeView1.Nodes.Clear()
    13. 'DataSheet verfügbar machen über Interop.Excel
    14. Dim MyXls As New Microsoft.Office.Interop.Excel.Application With {
    15. .Visible = CheckBox1.Checked
    16. }
    17. Dim wb As Microsoft.Office.Interop.Excel.Workbook = MyXls.Workbooks.Open(sPfad)
    18. Dim Tabelle1 As Microsoft.Office.Interop.Excel.Worksheet = DirectCast(wb.Sheets(TextBox4.Text), Worksheet)
    19. 'Erstmal die Anzahl der Bereiche Laden.
    20. 'Gewisse Anzahl an Leeren Bereichen sind gleichgültig mit dem Ende
    21. Dim mFolderEndMax As Integer = CInt(NumericUpDown3.Value)
    22. 'Ausrichtung der Tabelle herausfinden <-> Horizontal = Ordner name aus der Zellen einer Zeile bilden
    23. 'Vertikal = Ordner name aus der Zellen einer spalte Bilden
    24. Dim lEmptyCells As Integer = 0 '<- Gezähle leere Zellen
    25. If RadioButton1.Checked Then '<- Horizontale ausrichtung
    26. Dim i As Integer = 1 '<- Localer Schrittgeber
    27. Dim cellName As String = String.Empty
    28. Do Until lEmptyCells = mFolderEndMax ' <- Solange zählen bis lEmptyCells gleich dem eingestellten Wert ist
    29. cellName = "A" & i
    30. If Not DirectCast(Tabelle1.Range(cellName).Value, String) = String.Empty Then
    31. 'Ordnernamen als veränderbare Structur erstellen
    32. Dim lBeetwenCell As List(Of String) = CreateBeetwenArr(TextBox3.Text, m_replace_char)
    33. 'Wenn die Stückelung des Namens die der Liste überschreitet, wird das letzte Zeichen
    34. 'auf alle weitere Bereiche erweitert.
    35. Dim tmpom As New List(Of String)
    36. Dim innerlEmptyCells As Integer = 0
    37. Dim innerlSchritt As Integer = 1
    38. Dim tmpFolderName As String = String.Empty
    39. Do Until innerlEmptyCells = CInt(NumericUpDown4.Value) ' <- der Namen nun erstellen.
    40. If Not DirectCast(Tabelle1.Range(cellName).Value, String) = String.Empty Then
    41. 'Die Zelle ist nicht leer
    42. If CheckBox5.Checked Then
    43. If innerlSchritt <= lBeetwenCell.Count - 1 Then
    44. tmpFolderName &= lBeetwenCell.Item(innerlSchritt - 1) 'Normaler counter
    45. Else
    46. tmpFolderName &= lBeetwenCell.Item(lBeetwenCell.Count - 1) 'Hier wird das letzte
    47. 'Zeichen der Betweenliste erweitert weil der Count nicht reicht
    48. End If
    49. End If
    50. tmpFolderName &= DirectCast(Tabelle1.Range(cellName).Value, String)
    51. tmpom.Add(DirectCast(Tabelle1.Range(cellName).Value, String))
    52. If Not CheckBox5.Checked Then
    53. If innerlSchritt <= lBeetwenCell.Count - 1 Then
    54. tmpFolderName &= lBeetwenCell.Item(innerlSchritt - 1) 'Normaler counter
    55. Else
    56. tmpFolderName &= lBeetwenCell.Item(lBeetwenCell.Count - 1) 'Hier wird das letzte
    57. 'Zeichen der Betweenliste erweitert weil der Count nicht reicht
    58. End If
    59. End If
    60. 'innerlEmtpy = 0
    61. innerlEmptyCells = 0
    62. Else
    63. innerlEmptyCells += 1
    64. End If
    65. 'Nächster Zellenname erstellen
    66. innerlSchritt += 1
    67. cellName = CL(innerlSchritt) & i
    68. Loop
    69. 'Der Namen ist nun vorhanden und kann in die globale Liste eingefügt werden#
    70. 'Erst auf die maximale Länge überprüfen
    71. If Not CheckBox2.Checked And
    72. tmpFolderName.Length > 256 Then
    73. tmpFolderName = tmpFolderName.Substring(0, 256)
    74. End If
    75. If CheckBox2.Checked And tmpFolderName.Length > CInt(NumericUpDown2.Value) Then
    76. tmpFolderName = TrimString(tmpFolderName)
    77. End If
    78. If tmpFolderName.Contains("*") Or
    79. tmpFolderName.Contains("<") Or
    80. tmpFolderName.Contains(">") Or
    81. tmpFolderName.Contains("\") Or
    82. tmpFolderName.Contains("|") Or
    83. tmpFolderName.Contains("/") Or
    84. tmpFolderName.Contains(":") Then
    85. If CheckBox6.Checked Then
    86. tmpFolderName = tmpFolderName.Replace("<", "")
    87. tmpFolderName = tmpFolderName.Replace(">", "")
    88. tmpFolderName = tmpFolderName.Replace("/", "")
    89. tmpFolderName = tmpFolderName.Replace("|", "")
    90. tmpFolderName = tmpFolderName.Replace("/", "")
    91. tmpFolderName = tmpFolderName.Replace("*", "")
    92. tmpFolderName = tmpFolderName.Replace(":", "")
    93. Dim t As New TmpOrdner(lBeetwenCell, mPfad, tmpFolderName)
    94. t.SetElementList() = tmpom
    95. mtmpOrdner.Add(t) 'Structur mit nötigen Daten erstellt
    96. End If
    97. Else
    98. Dim t As New TmpOrdner(lBeetwenCell, mPfad, tmpFolderName)
    99. t.SetElementList() = tmpom
    100. mtmpOrdner.Add(t) 'Structur mit nötigen Daten erstellt
    101. End If
    102. lEmptyCells = 0 ' <- reset
    103. Else
    104. 'Leerer Bereich
    105. lEmptyCells += 1 ' <- Erhöhen
    106. End If
    107. i += 1 '<- Schritt erhöhen
    108. Loop
    109. ElseIf RadioButton2.Checked Then '<- Vertikale Ausrichtung
    110. Dim i As Integer = 1 '<- Localer Schrittgeber
    111. Dim cellName As String = String.Empty
    112. Do Until lEmptyCells = mFolderEndMax ' <- Solange zählen bis lEmptyCells gleich dem eingestellten Wert ist
    113. cellName = CL(i) & 1
    114. Dim tmpom As New List(Of String)
    115. If Not DirectCast(Tabelle1.Range(cellName).Value, String) = String.Empty Then
    116. 'Ordnernamen als veränderbare Structur erstellen
    117. Dim lBeetwenCell As List(Of String) = CreateBeetwenArr(TextBox3.Text, m_replace_char)
    118. 'Wenn die Stückelung des Namens die der Liste überschreitet, wird das letzte Zeichen
    119. 'auf alle weitere Bereiche erweitert.
    120. Dim innerlEmptyCells As Integer = 0
    121. Dim innerlSchritt As Integer = 1
    122. Dim tmpFolderName As String = String.Empty
    123. Do Until innerlEmptyCells = CInt(NumericUpDown4.Value) ' <- der Namen nun erstellen.
    124. If Not DirectCast(Tabelle1.Range(cellName).Value, String) = String.Empty Then
    125. 'Die Zelle ist nicht leer
    126. If CheckBox5.Checked Then
    127. If innerlSchritt <= lBeetwenCell.Count - 1 Then
    128. tmpFolderName &= lBeetwenCell.Item(innerlSchritt - 1) 'Normaler counter
    129. Else
    130. tmpFolderName &= lBeetwenCell.Item(lBeetwenCell.Count - 1) 'Hier wird das letzte
    131. 'Zeichen der Betweenliste erweitert weil der Count nicht reicht
    132. End If
    133. End If
    134. tmpFolderName &= DirectCast(Tabelle1.Range(cellName).Value, String)
    135. tmpom.Add(DirectCast(Tabelle1.Range(cellName).Value, String))
    136. If Not CheckBox5.Checked Then
    137. If innerlSchritt <= lBeetwenCell.Count - 1 Then
    138. tmpFolderName &= lBeetwenCell.Item(innerlSchritt - 1) 'Normaler counter
    139. Else
    140. tmpFolderName &= lBeetwenCell.Item(lBeetwenCell.Count - 1) 'Hier wird das letzte
    141. 'Zeichen der Betweenliste erweitert weil der Count nicht reicht
    142. End If
    143. End If
    144. 'innerlEmtpy = 0
    145. innerlEmptyCells = 0
    146. Else
    147. innerlEmptyCells += 1
    148. End If
    149. 'Nächster Zellenname erstellen
    150. innerlSchritt += 1
    151. cellName = CL(i) & innerlSchritt
    152. Loop
    153. 'Der Namen ist nun vorhanden und kann in die globale Liste eingefügt werden#
    154. If Not tmpFolderName = String.Empty Then
    155. 'Erst auf die maximale Länge überprüfen
    156. If Not CheckBox2.Checked And
    157. tmpFolderName.Length > 256 Then
    158. tmpFolderName = tmpFolderName.Substring(0, 256)
    159. End If
    160. If CheckBox2.Checked And tmpFolderName.Length > CInt(NumericUpDown2.Value) Then
    161. tmpFolderName = TrimString(tmpFolderName)
    162. End If
    163. 'Dann Sonderzeichen durchgehen
    164. If tmpFolderName.Contains("*") Or
    165. tmpFolderName.Contains("<") Or
    166. tmpFolderName.Contains(">") Or
    167. tmpFolderName.Contains("\") Or
    168. tmpFolderName.Contains("|") Or
    169. tmpFolderName.Contains("/") Or
    170. tmpFolderName.Contains(":") Then
    171. If CheckBox6.Checked Then
    172. tmpFolderName = tmpFolderName.Replace("<", "")
    173. tmpFolderName = tmpFolderName.Replace(">", "")
    174. tmpFolderName = tmpFolderName.Replace("/", "")
    175. tmpFolderName = tmpFolderName.Replace("|", "")
    176. tmpFolderName = tmpFolderName.Replace("/", "")
    177. tmpFolderName = tmpFolderName.Replace("*", "")
    178. tmpFolderName = tmpFolderName.Replace(":", "")
    179. Dim t As New TmpOrdner(lBeetwenCell, mPfad, tmpFolderName)
    180. t.SetElementList() = tmpom
    181. mtmpOrdner.Add(t) 'Structur mit nötigen Daten erstellt
    182. End If
    183. Else
    184. Dim t As New TmpOrdner(lBeetwenCell, mPfad, tmpFolderName)
    185. t.SetElementList() = tmpom
    186. mtmpOrdner.Add(t) 'Structur mit nötigen Daten erstellt
    187. End If
    188. End If
    189. lEmptyCells = 0 ' <- reset
    190. Else
    191. 'Leerer Bereich
    192. lEmptyCells += 1 ' <- Erhöhen
    193. End If
    194. i += 1 '<- Schritt erhöhen
    195. Loop
    196. End If
    197. 'Bereich Reinigen
    198. MyXls.Quit()
    199. MyXls = Nothing
    200. CreateTreeViewControl()
    201. End Sub

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

    Farliam schrieb:

    Also ist das eine Eigenart der Structur die ich nicht kenne?
    Eine Struktur verhält sich da wie eine Variable, sie ist ein ValueType:
    Mit Dim var As TmpOrdner hast Du eine Instanz.
    Eine Klasse musst Du mit New instanziieren:
    Dim var2 As New TmpOrdner2
    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!
    Okay, ich habe die Structur (siehe mein Code) vorher auch mit New instanziert. Habe ja nur die Beschreibung der TmpOrdner geändert.
    Auf die Klasse kann ich nach dem erstellen in der Liste zugreifen, auf eine Structur nur ReadOnly.

    Dass ist das, was ich nicht ganz verstehe.

    Farliam schrieb:

    auf eine Structur nur ReadOnly.
    schon das stimmt nicht - aber egal.

    Den Unterschied bei Structure und Class machen die Variablen aus, denen man son Ding zuweist.

    Auf eine ValueType-Variable (Structure) wird eine Kopie der kompletten Structure geschrieben - das sind bei deinem TmpOrdner-Dingens mit 4 Membern: 32 Bytes.

    Auf eine ReferenceType-Variable wird nur ein Zeiger auf das Objekt geschrieben - das sind immer 4 Bytes.

    Wenn du also einen ValueType an eine Methode übergibst, dann übergibst du ihm eine Kopie des Objekts.
    Da kann die Methode natürlich alles mögliche mit machen - sie macht es immer nur mit einer Kopie - das Original, beim Aufrufer, bleibt davon gänzlich unberührt.

    Wenn du aber einen ReferenceType an eine Methode übergibst, dann übergibst du einen Zeiger auf das Objekt.
    Also es gibt nur ein Objekt, und was die Methode auf diesem Zeiger macht, das macht sie auf dem Original-Objekt - es gibt ja garkein anderes.
    Das Objekt beim Aufrufer und das Objekt in der Methode ist dasselbe.