Listbox sortieren und danach identische Paare anzeigen

  • VB.NET

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

    Listbox sortieren und danach identische Paare anzeigen

    Hallo Leute,

    und zwar bräuchte ich Hilfe beim Sortieren einer Listbox, welche so aussieht.
    Spoiler anzeigen

    12.7.11
    12.7.11
    12.7.11
    11.7.11
    11.7.11
    11.7.11
    10.7.11
    10.7.11
    10.7.11
    9.7.11
    9.7.11


    Diese ganzen Items der ListBox sollten dann verglichen werden, nach dem die identischen items gefunden wurden, soll nur jeweils ein Item von den identischen Items übrig bleiben, sprich :
    Spoiler anzeigen

    Es gibt 3 Items mit "12.7.11", 3 mit "11.7.11" , 3 mit "10.7.11" und 2 mit "9.7.11"

    Von jedem dieser identischen "Paare" soll immer nur ein Item übrig bleiben, also

    12.7.11
    11.7.11
    10.7.11
    9.7.11


    Dieses Verfahren brauche ich für mein News Tool, damit die News Meldungen die an dem selben Tag verfasst wurden alle unter einander aufgelistet werden ( es geht mir nur um das Kästchen mit dem Datum siehe Anhang), die News Title werden jeweils untereinander in einer Toolbar angezeigt.

    So sieht der Code zum Auslesen der News aus, damit ihr dass alles vielleicht besser verstehen könnt :


    VB.NET-Quellcode

    1. Imports <xmlns:content="http://purl.org/rss/1.0/modules/content/">
    2. Imports <xmlns:dc="http://purl.org/dc/elements/1.1/">

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    3. show_rss_linq()
    4. End Sub
    5. Sub show_rss_linq()
    6. Dim xdoc As XDocument = XDocument.Load("http://www.idev-world.de/forum/syndication.php?fid=118,103,143,144,145,146,147,141,10,52&limit=38") 'Einladen des RSS Feeds
    7. ListBox1.Items.Clear()
    8. ListBox4.Items.Clear()
    9. ListBox3.Items.Clear()
    10. ListBox2.Items.Clear()
    11. For Each result In xdoc.Descendants("item")
    12. Dim title As String = result.Element("title").Value
    13. Dim time As String = DateTime.Parse(result.Element("pubDate").Value)
    14. time = time.Substring(0, 10)
    15. ListBox5.Items.Add(time)
    16. title = title.Replace("#x26;", "&")
    17. title = title.Replace("&&", "&")
    18. With ListBox1.Items.Add(title)
    19. ListBox2.Items.Add(result.Element("link").Value)
    20. ListBox3.Items.Add(DateTime.Parse(result.Element("pubDate").Value))
    21. ListBox4.Items.Add(result.Element("description").Value)
    22. ToolBar1.Buttons.Add(title)
    23. End With
    24. Next
    25. End Sub

    Ich hoffe ihr könnt mir ein wenig weiterhelfen ;)

    Viele Grüße ,

    Flow
    Bilder
    • IMG_0302[2].PNG

      241,96 kB, 640×960, 181 mal angesehen
    ich würde dringend empfehlen, gscheite Datenklassen anzulegen, anstatt die Properties auf 4 Listboxen zu verstreuen.

    So eine Datenklasse könnte Time, Title, Link, PubTime, Description als Properties aufweisen.

    Davon eine Liste aus dem Xml befüllen.
    Dieselbe Liste könnte allen Listboxen als Datasource angedreht werden, und je Listbox wird per DisplayMember festgelegt, dass eine annere Property anzuzeigen ist.

    Oder den ganzen Sermon gleich in ein DatagridView.

    Jedenfalls zum Gruppieren: O.g. Datenklassen kann man wunnebar mit Linq gruppieren:

    VB.NET-Quellcode

    1. Dim groups = From itm in Items Group itm by itm.Time Into Group
    (Iwie so war die Syntax.)

    Into Group brauchstenur, wennde noch auf die Elemente innerhalb der Gruppen zugreifen willst

    ErfinderDesRades schrieb:

    ich würde dringend empfehlen, gscheite Datenklassen anzulegen, anstatt die Properties auf 4 Listboxen zu verstreuen.

    So eine Datenklasse könnte Time, Title, Link, PubTime, Description als Properties aufweisen.

    Davon eine Liste aus dem Xml befüllen.
    Dieselbe Liste könnte allen Listboxen als Datasource angedreht werden, und je Listbox wird per DisplayMember festgelegt, dass eine annere Property anzuzeigen ist.

    Oder den ganzen Sermon gleich in ein DatagridView.

    Jedenfalls zum Gruppieren: O.g. Datenklassen kann man wunnebar mit Linq gruppieren:

    VB.NET-Quellcode

    1. Dim groups = From itm in Items Group itm by itm.Time Into Group
    (Iwie so war die Syntax.)

    Into Group brauchstenur, wennde noch auf die Elemente innerhalb der Gruppen zugreifen willst
    Ist dies [VB.NET] Tutorial über das Speichern und Laden von XML-Dateien ein Gutes Tutorial zum Erstellen von Klassen und das Laden von Xml Dateien ?

    picoflop schrieb:

    VB.NET-Quellcode

    1. Dim l As New List(Of String) From {"1", "1", "2", "2", "3"}
    2. Dim result As IEnumerable(Of String) = l.Distinct
    Schuldige, wenn ich noch mal nachfrage, aber da ich mich noch nicht sehr lange mit visual basics beschäftige, müsstest du mir dass vielleicht noch ein wenig erläutern ;)


    Gruß Flow
    Distinct -> Selektiere jedes "gleiche" Element nur exakt genau einmal. Das ganze liefert dann halt eine Aufzählung (Enumeration) vom Typ "String". Wenn deine Werte nicht String sind, sonder "foo", macht das keinen Unterschied.

    Flow96 schrieb:

    Ist dies [VB.NET] Tutorial über das Speichern und Laden von XML-Dateien ein Gutes Tutorial zum Erstellen von Klassen und das Laden von Xml Dateien ?

    Nein, nicht ganz. Dort werden alle Daten in ein Objekt gelesen und serialisiert.
    Unter Datenklasse würde ich sowas wie die dortige Structure Address verstehen - jedoch sollte man für Datenklassen keine Structure nehmen, sondern Class.

    @picoflop: Ja, Distinct löst streng gesehen die Frage. Aber wenn man sich das Bild anguckt - willerwohl auf eine Gruppierungs-Methode hinaus - so versteh ich das jdfs.

    ErfinderDesRades schrieb:

    Flow96 schrieb:

    Ist dies [VB.NET] Tutorial über das Speichern und Laden von XML-Dateien ein Gutes Tutorial zum Erstellen von Klassen und das Laden von Xml Dateien ?

    Nein, nicht ganz. Dort werden alle Daten in ein Objekt gelesen und serialisiert.
    Unter Datenklasse würde ich sowas wie die dortige Structure Address verstehen - jedoch sollte man für Datenklassen keine Structure nehmen, sondern Class.

    @picoflop: Ja, Distinct löst streng gesehen die Frage. Aber wenn man sich das Bild anguckt - willerwohl auf eine Gruppierungs-Methode hinaus - so versteh ich das jdfs.
    Ja ich hatte halt eigentlich an die Gruppierung gedacht, dazu hatte ich mir vorgestellt, dass jedes Element aus ListBox5 ( also die Zeit Angaben ) nur einmal vorhanden ist und ich so die News besser gruppieren kann.
    Also

    Bastel dir eine passende Datenklasse, dann kannste die Daten gruppieren. Und die Gruppen werden sehr anders angezeigt als die Daten.
    Jdfs. der erste Schritt ist, die Datenklasse zu proggen, und dafon eine List(Of ) zu befüllen.

    Übrigens - muss das sein, dass du bei jeder Antwort den komplettText des vorherigen Postes zitierst? (dieses ist eine rethorische Frage, denn es muß nicht sein ;))
    So hab mir jetzt die passende Datenklasse für den Titel, Zeit , Beschreibung und Link gebastelt.

    VB.NET-Quellcode

    1. Dim Cabinet As List(Of news) = New List(Of news)



    VB.NET-Quellcode

    1. Private Sub listfill()
    2. Cabinet.Clear()
    3. For Each result In xdoc.Descendants("item")
    4. Dim time As String = DateTime.Parse(result.Element("pubDate").Value)
    5. Dim link As String = (result.Element("link").Value)
    6. Dim title As String = (result.Element("title").Value)
    7. Dim descr As String = (result.Element("description").Value)
    8. Cabinet.Add(New news( _
    9. title, _
    10. time, _
    11. descr, link))
    12. Next


    VB.NET-Quellcode

    1. Public Class news
    2. Public title As String
    3. Public time As String
    4. Public description As String
    5. Public link As String
    6. Public Sub New( _
    7. ByVal m_title As String, _
    8. ByVal m_time As String, _
    9. ByVal m_description As String, _
    10. ByVal m_link As String)
    11. title = m_title
    12. time = m_time
    13. description = m_description
    14. link = m_link
    15. End Sub
    16. End Class


    VB.NET-Quellcode

    1. Sub displaynews(ByVal b As news)
    2. ListBox6.Items.Add( _
    3. b.title & " - " & _
    4. b.time & " - " & _
    5. b.description & " - " & _
    6. b.link)
    7. End Sub
    8. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    9. listfill()
    10. ListBox6.Items.Clear()
    11. Cabinet.ForEach(AddressOf displaynews)
    12. End Sub


    Jetzt habe ich die Daten in eine List gepackt, nur wie muss ich jetzt weiter vorgehen ?
    Sortieren kann ich ja z.B hiermit


    VB.NET-Quellcode

    1. Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    2. listfill()
    3. ListBox6.Items.Clear()
    4. Cabinet.Sort(AddressOf sortCabinet)
    5. For Each r As news In Cabinet
    6. ListBox6.Items.Add( _
    7. r.title & " - " & _
    8. r.time & " - " & _
    9. r.description & " - " & _
    10. r.link)
    11. Next
    12. End Sub
    13. Private Shared Function sortCabinet( _
    14. ByVal x As news, ByVal y As news) As Integer
    15. Return x.title.CompareTo(y.title)
    16. End Function


    Aber ich hab im Moment das Problem, dass ich nicht weiß wie nur der Titel der News angezeigt wird ohne Description, Link und Time, als nächstes stellt sich die Frage, wie ist es möglich, dass wenn ich auf den Title ( als Beispiel ein Item in der ListBox ) klicke und dann die dazugehörige Beschreibung in einer MsgBox angezeigt wird ?

    EDIT : Diese Frage hat sich schon erledigt


    VB.NET-Quellcode

    1. Dim a As String = Cabinet.Item(ListBox6.SelectedIndex).description
    2. MsgBox(a)


    Jetzt hab ich nur noch meine eigentliche Frage, wie ich die News nach ihrem Erscheinungsdatum unter dem jeweiligen Kästchen mit dem Datum auflisten kann ?

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

    das habich prinzipiell in meim ersten Post beantwortet - nämlich gruppieren.
    Aber deine Datenklasse ist dafür noch nicht ausreichend - Time muß natürlich ein DateTime sein, kein String.

    Und dann wirds etwas ungemütlich in WinForms, da bleibt eim nich viel übrig, als die ListboxItem selbst zu zeichnen - nach typ unterscheidend.
    Dazu muß man die Gruppierungs-Hierarchie gleich wieder plätten.

    also wennde deine Datenklasse noch ordentlich machst, und Code zur Generierung von Beispieldatensätzen bereitstellst, kann ich das basteln.

    allerdings ist dann vmtl. deine nächste Frage, ob man die in der Listbox dargestellten Gruppen nicht auch kollabieren könnte - und das wäre mir dann zu viel.
    Also erstmal recht herzlichen Dank, dass du dich so engagierst und mir auch deine konkrete Hilfe anbietest.
    Nur könntest du mir vielleicht bitte ein par Links schicken von denen du meist, dass diese passend sind ( also für Gruppierungs-Hierarchie plätten und Beispieldatensätzen ), damit ich meinen Teil verbringen kann. Und was versteht man unter " ListboxItem selbst zu zeichnen" ?
    Also aus diesem Post habich Beispieldaten entnehmen können, und darunter dann ein Einlesen in eine Auflistung von Datenklassen entwickelt, inklusive Gruppierung.
    Ich hoffe, dir ist genau klar, was eine Gruppierung macht, ja? Die erstellt nämlich eine baumartige Struktur (Hierarchie).

    Etwa aus

    Quellcode

    1. 275357,1310753262,1384833,1977749
    2. 287911,1310754487,1352562,1432893
    3. 240078,1310754547,317117,1531420
    4. 240078,1310754621,2286265,0
    5. 275357,1310753222,1781491,2320926
    6. 240078,1310754689,1465879,0
    7. 275357,1310753863,1413321,0
    8. 275357,1310753863,317117,1531420
    9. 287911,1310754394,1580990,0
    10. 240078,1310754860,2293747,0
    11. 275357,1310754143,1547112,0


    wird so eine Hierarchie gebildet:

    Quellcode

    1. 275357
    2. 275357,1310753222,1781491,2320926
    3. 275357,1310753262,1384833,1977749
    4. 275357,1310753863,1413321,0
    5. 275357,1310753863,317117,1531420
    6. 275357,1310754143,1547112,0
    7. 287911
    8. 287911,1310754394,1580990,0
    9. 287911,1310754487,1352562,1432893
    10. 240078
    11. 240078,1310754547,317117,1531420
    12. 240078,1310754621,2286265,0
    13. 240078,1310754689,1465879,0
    14. 240078,1310754860,2293747,0
    wobei die nach links rausgerückten Zahlen Nodes bedeuten (ähnlich den Treenodes), die einerseits den Gruppenschlüssel angeben (eben die Zahl), aber ausserdem eine Liste enthalten mit den in diese Gruppe fallenden datensätzen. Die Hierarchie ist also hier eine Liste mit 3 Nodes, mit 5, 2, und 4 SubNodes (Blätter)

    So eine Hierarchie lässt sich nicht in einer listbox abbilden (Treeview ginge) - das ergäbe nur 3 ListboxItem. Daher würdichsie wieder plattklopfen:

    Quellcode

    1. 275357
    2. 275357,1310753222,1781491,2320926
    3. 275357,1310753262,1384833,1977749
    4. 275357,1310753863,1413321,0
    5. 275357,1310753863,317117,1531420
    6. 275357,1310754143,1547112,0
    7. 287911
    8. 287911,1310754394,1580990,0
    9. 287911,1310754487,1352562,1432893
    10. 240078
    11. 240078,1310754547,317117,1531420
    12. 240078,1310754621,2286265,0
    13. 240078,1310754689,1465879,0
    14. 240078,1310754860,2293747,0


    Jetzt enthalten die Zahlen-Nodes keine Listen mehr (sind daher keine Nodes mehr), sondern es ist nurnoch eine GesamtListe, mit auch noch verschiedenen Arten von Datensätzen drin.
    Sowas kann man in einer Listbox anzeigen, allerdings müsste man die verschiedenartigen Datensätze auch entsprechend verschiedenartig zeichnen.
    Zum Zeichnen mal hierwas. Das ist selbst gezeichnet, um einen Spaltensatz zu erhalten. Es ist aber keine selbstgezeichnete Hierarchie, sondern alle "Datensätze" sind gleich - (Strings mit Tabulatoren).
    news ist eine Klasse (und die Time-Property muss type DateTime kriegen). Datenbeispiele sind Datenbeispiele - halt Daten, mit denen man herumexperimentieren kann.
    Habe dirja einen Link gezeigt, der einen haufen Zahlen enthielt, und damit konnteman was tun.
    kann doch nicht so schwer sein, ein paar news-Objekte zu erstellen.