Inhalt ListBox richtig definieren

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

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

    Inhalt ListBox richtig definieren

    Hallo,

    ich erstelle eine ListBox1 aus Dateinamen, alle 20 Sekunden erstelle ich eine neue Liste Dateinamen und vergleiche mit der ListBox1, wenn ein Eintrag nicht enthalten ist, soll er in die Listbox2 kommen. ListBox1 wird anschließend überschrieben mit der neuen Liste Dateien. Nur schreibt er mir hier immer alle Items in ListBox2, ich denke mal ich hab Contains nicht richtig verwendet.
    Also er schreibt auch Files in ListBox2 die schon in ListBox1 stehen.

    VB.NET-Quellcode

    1. arroFilesalt = objPath.GetFiles()
    2. For i = 0 To UBound(arroFilesalt)
    3. ListBox1.Items.Add(arroFilesalt(i))
    4. Next i
    5. ...
    6. For i = 0 To UBound(arroFilesneu)
    7. If Not ListBox1.Items.Contains(arroFilesneu(i)) Then
    8. ListBox2.Items.Add(arroFilesneu(i))
    9. End If
    10. Next i


    Kontextcode:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public strpath As String
    2. Public objPath As DirectoryInfo
    3. Public arroFilesneu As FileInfo()
    4. Public arroFilesalt As FileInfo()
    5. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. strpath = "C:\pfad"
    7. objPath = New DirectoryInfo(strpath)
    8. Timer1.Interval = 20000
    9. Timer1.Start()
    10. arroFilesalt = objPath.GetFiles()
    11. For i = 0 To UBound(arroFilesalt)
    12. ListBox1.Items.Add(arroFilesalt(i))
    13. Next i
    14. End Sub
    15. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    16. arroFilesneu = objPath.GetFiles()
    17. ListBox2.Items.Clear()
    18. For i = 0 To UBound(arroFilesneu)
    19. If Not ListBox1.Items.Contains(arroFilesneu(i)) Then
    20. ListBox2.Items.Add(arroFilesneu(i))
    21. End If
    22. Next i
    23. ListBox1.Items.Clear()
    24. For i = 0 To UBound(arroFilesneu)
    25. ListBox1.Items.Add(arroFilesneu(i))
    26. Next i
    27. ...
    28. End Sub

    Es stehen immer die gleichen Einträge in ListBox1 und 2. Denn Du löschst alle Einträge (Zeile#19, #26) und fügst alle Dateinamen hinzu.

    Bevor Du weitermachst, bitte die empfohlenen VS-Einstellungen verwenden. Stichwort UBound. Das Hinzufügen geht auch einfacher: ListBox1.Items.AddRange(arroFilesalt). Und kümmer Dich am besten zeitnah um gute Benennung. ListBox1? arroFilesneu?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Nach Zeile#13 habe ich in ListBox1 die Dateien des Pfades. Nach 20 Sekunden werden die Dateien neu in ein Array eingelesen. ListBox2 ist momentan noch leer, aber falls nicht soll sie geleert werden. Dann befülle ich mit Zeile#20 bis 24 die ListBox2 mit allen Dateien, die im neuen Array, aber nicht in Listbox1 sind, danach leere ich ja erst ListBox1. Der Code wird doch von oben nach unten zeitversetzt abgearbeitet?

    ListBox2 sollte also leer bleiben wenn die Dateien gleich bleiben, aber stattdessen befüllt er ListBox2. Der einzige Befehl der listBox 2 befüllt, ist in der If-Kontrolle.

    Also in meinem Test ist arroFilesneu = arroFilesalt, ich hätte daher gedacht, dass arroFilesneu(i) in ListBox1 enthalten ist.

    Was ist denn die Alternative zu Ubound?

    Nachtrag: Wenn ich in arroFilesneu(0) reinschaue habe ich da z.B. {eins.txt} stehen, werden ListBox.Items als "eins.txt" ausgegeben oder auch {eins.txt} ?

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Haudruferzappeltnoch schrieb:

    Was ist denn die Alternative zu Ubound?
    .Length - 1
    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!
    Argh. Denkfehler. Das Problem ist, dass Du mit Objekten (in dem Fall von Typ IO.FileInfo) arbeitest. Zwei FileInfo-Objekte, die auf dieselbe Datei verweisen, sind nicht identisch, werden also nicht von Contains mit True erkannt. Daher darfst Du nicht die Objekte vergleichen, sondern z.B. FullPath, also den kompletten Dateipfad. Wird nur vom Coden her komplizierter:

    VB.NET-Quellcode

    1. For i = 0 To arroFilesneu.Count - 1 'das ist eine Alternative zu UBound
    2. Dim j = i 'weil der Compiler meckert, wenn man beim LINQ-Ausdruck i wiederverwendet V
    3. If Not ListBox1.Items.Cast(Of IO.FileInfo).Any(Function(x) x.FullName = arroFilesneu(j).FullName) Then
    4. ListBox2.Items.Add(arroFilesneu(i))
    5. End If
    6. Next i

    ach ja: Next i geht auch mit Next ohne i
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ah sowas hab ich mir gedacht nur nicht so kompliziert^^

    Dann brauche ich ja nicht unbedingt die FileInfo in der ListBox.
    Mit kompletter Dateipfad ist, dann auf C:\... usw. drin?

    Ich hab es mit FileInfo.Name versucht, ich dachte mehr stellt FileInfo garnicht bereit^^

    Allerdings kann ich AddRange so nicht mehr verwenden oder?

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public strpath As String
    3. Public objPath As DirectoryInfo
    4. Public arroFilesneu As FileInfo()
    5. Public arroFilesalt As FileInfo()
    6. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    7. strpath = "C:\pfad"
    8. objPath = New DirectoryInfo(strpath)
    9. Timer1.Interval = 20000
    10. Timer1.Start()
    11. arroFilesalt = objPath.GetFiles()
    12. For i = 0 To arroFilesalt.Length - 1
    13. ListBox1.Items.Add(arroFilesalt(i).Name)
    14. Next i
    15. End Sub
    16. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    17. arroFilesneu = objPath.GetFiles()
    18. ListBox2.Items.Clear()
    19. For i = 0 To arroFilesneu.Length - 1
    20. If Not ListBox1.Items.Contains(arroFilesneu(i).Name) Then
    21. ListBox2.Items.Add(arroFilesneu(i))
    22. End If
    23. Next i
    24. ListBox1.Items.Clear()
    25. For i = 0 To arroFilesneu.Length - 1
    26. ListBox1.Items.Add(arroFilesneu(i).Name)
    27. Next i
    28. End Sub
    29. End Class


    Vielen Dank
    Puh … und dann bitte gleich noch Option Strict On, ganz wichtig!
    Nein, AddRange geht so nicht mehr. Da Du fügst ja nun einen Teil von arroFilesneu (nämlich den Dateinamen) hinzu. Das ginge mit Deiner For-Loop oder eben wieder mit LINQ:

    VB.NET-Quellcode

    1. ListBox1.Items.AddRange(arroFilesalt.Select(Function(x) x.Name).ToArray)

    Aber: Keine Strings in die File-ListBox!
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Danke für den Hinweis, aber in meinem Fall ändert sich der Pfad nie.

    Zu LINQ: Select wählt da jedes Element von arroFilesalt einzeln oder wie kann man das verstehen?

    Option strict on hab ich nicht ganz verstanden.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Deshalb der Hinweis bezüglich des Threads empfohlene VisualStudio-Einstellungen; anklicken, durchlesen, beherzigen, anwenden.

    LINQ: Ja, Select wählt quasi für alle Elemente einer Ansammlung eine gemeinsame Eigenschaft und gibt dieses als aufzählbare Ansammlung (IEnumerable(Of WasAuchImmer)) zurück.
    So wird z.B. aus einem FileInfo-Array mittels Select ein IEnumerable(Of String), welches die Namen der Dateien enthält. Man kann das Ganze noch in ein Array umwandeln, falls man der Meinung ist, dass man das braucht, und so wird aus einem FileInfo-Array ein String-Array:

    VB.NET-Quellcode

    1. Dim ArrayOfFileInfos = objPath.GetFiles()
    2. Dim ArrayOfNamesOfThoseFiles = FileInfoArray.Select(Function(x) x.Name).ToArray

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Naja es geht noch um Option Strict On und die dazu eingangs vorgeschlagene Lektüre, das hätte ich wohl nochmal aufgreifen können.

    Ein Bugtester sollte möglichst Bugs finden, da wird man schnell kreativ. Gerade die irrealeren Kombinationen sind da vielversprechender.
    Das kein natürlicher Weg an das Problem heranführt, meine ich dahingehend, dass ich mir keine Situation denken kann, wo ich so nebenbei einen Integer mit einem String befüllen könnte.

    Versteh mich nicht falsch, die wird es bestimmt geben, aber ist halt nicht angegeben. Daher fehlt mir dementsprechend weiterhin das Verständnis zu dem Option Strict On Beitrag.
    Deswegen hab ich nachgefragt, aber das wird dann ja gerne wieder verulkt.

    Ich bin euch dankbar für die Hilfe, ihr seid nicht dazu verpflichtet. Aber diese loopende Verweise sind da nicht Lösung. Wenn ihr einen Grund für die Frage braucht könnt ihr das auch ganz normal erfragen, da bin ich nicht bös drum.
    Sorry, wenn es so rüberkam, aber wir tendieren selten dazu, jemanden zu verulken. Da heute schon ein anderer User das Gefühl hatte, muss aber wohl was dran sein. Nur leider kann man den Tonfall nicht schreiben.
    Ich hatte das Thema ins Spiel gebracht, weil ich das Gefühl hatte, dass es bei Dir ausgeschaltet ist. Die Option lässt einen Fehler zur Codingzeit sehen, die sonst erst zur Laufzeit auftauchen. Wenn bei Dir alles ohne geht, sehr gut. Option Strict auf On schalten und VB6-Namespace raus sind nur die ersten Empfehlungen, die hier im Forum grundsätzlich ausgesprochen werden, damit zielgerichtet(er) programmiert wird, ohne dass einem sowas auf die Füße fällt. Denn wenn wegen solchen Sachen Ratlosigkeit auftritt und damit vermeidbare Fragen auftreten, dann geht einmal mehr ein Raunen durch's Forum. Sei's drum, ich hab das mit dem Option Strict On ohne konkreten Vorfall in Deinem Code angefangen, war keine Boshaftigkeit oder ich-mach-mir-ein-Spaß-die-Neuzugänge-zu-ärgern, sondern ein anlassfreier Schuss aus der Hüfte. Einen loopenden Verweis hab ich jetzt nicht auf dem Schirm. Die Verlinkung kam 2x von mir, einmal m.E. berechtigt (Post#2), einmal war es Redundanz.
    Post#10 hatte ich auch nicht verstanden. Vielleicht bin ich zu lange wach …
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Nein, das ist auch überhaupt nicht schlimm. Ich finde den Hinweis super. Allerdings wollte ich ihn auch voll durchdringen. Da hatte ich mehr das Gefühl das meine Fragen als Ablehnung des Tipps gedeutet wurden.
    Für mich ist das im Moment immernoch etwas das sicherlich richtig ist, aber in der Luft schwebt.

    Was ich mit dem Loop meine ist, ich lese das, kann es leider nicht nachvollziehen und bekomme den Hinweis lies doch nochmal.
    Ich fühle mich hier nicht angegriffen! Ich freue mich hier Hilfe zu finden, aber ich musste es benennen, damit man weiß wieso die Konversation so schleppend vorangeht.

    Was ich ausdrücken will ist, dass der Beitrag zu Option Strict On ein sehr un-alltägliches Beispiel anführt, mag vllt. auch nur mir so gehen. Ich meine, um es mal auf andere Weise zu probieren:
    Gibts es irgendeinen Vorteil von Option Strict Off?

    Haudruferzappeltnoch schrieb:

    Gibts es irgendeinen Vorteil von Option Strict Off?
    Es stellt eine gewisse Kompatibilität zu älteren BASIC- und VisualBasic (nicht .NET) her.
    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!
    Vorteil von Option Strict Off ist, dass der Compiler versucht Dir Dinge abzunehmen, um die Du Dir gedanken machen solltest, in erster Linie (aber nicht nur!): die korrekte Verwendung (und Umwandlung) von Datentypen (ineinander). Spätestens wenn Datentypen inkompatibel sind, scheitert der Compiler zur Laufzeit bei Off. Bei On kompiliert das Programm erst gar nicht, sondern VS weist den Programmierer sofort darauf hin, dass da was nicht stimmt.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Zufällig ein Beispiel dazu gefunden, das ich nochmal hinterfragen wollte:

    Quellcode

    1. Option Strict On
    2. Module Module1
    3. Sub Main()
    4. Dim testarr As String
    5. testarr = "Hallo@"
    6. Console.WriteLine(Split(testarr, "@", -1, 1)(0))
    7. End Sub
    8. End Module


    Hier wird in der CompareMethod 1 nicht geduldet. Stattdessen ist vbTextCompare vorgesehen.

    Dazu habe ich mir die Seite angesehen: Allerdings wieder ohne Erfolg: docs.microsoft.com/de-de/dotne…omparemethod?view=net-5.0
    ich denke mal eigentlich heißt das es ist normal, dass er da eine 1 für vbTextCompare versteht.

    Haudruferzappeltnoch schrieb:

    Hier wird in der CompareMethod 1 nicht geduldet.
    Das ist korrekt, denn Du hast ja Option Strict On gewählt. :thumbup:
    In der Deklaration der Prozedur steht an dieser Position kein Integer-Wert, sondern den Typ CompareMethod (ein Enum).
    docs.microsoft.com/de-de/dotne…omparemethod?view=net-5.0
    Also erwartet er von Dir CompareMethod.vbTextCompare, das nach Konvertierung in ein Integer den Wert 1 hat.
    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!
    1. Mag sein, dass beide den Wert 1 haben, aber das ist mit Absicht. Typsicherheit, AFAIK.
    2. Deine Split-Methode ist VB6. Hinfort damit! ;)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.