Liste in zwei ListBoxen gruppieren

  • WPF

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

    Liste in zwei ListBoxen gruppieren

    Hey,
    ich habe eine Liste mit lauter Objekten, welche alle zB. die Eigenschaft Foo aufweisen. Foo ist vom Type:

    C#-Quellcode

    1. public enum Garcon
    2. {
    3. Foo1,
    4. Foo2
    5. }


    Jetzt habe ich eine riesige Liste (kann über 20k Items beinhalten), welche ich gerne nach dieser Eigenschaft in zwei Listboxen haben würde - in der linken ist die Eigenschaft und in der rechten dann die Items mit der selben Eigenschaft. Das ist ungefähr das gleiche wie mit der PropertyGroupDescription. Nochmal ein Beispiel:

    C#-Quellcode

    1. public class Foo
    2. {
    3. public Garcon Garcon { get; set; }
    4. public string Name { get; set; }
    5. }
    6. public enum Garcon
    7. {
    8. Foo1,
    9. Foo2
    10. }
    11. //Jetzt habe ich folgende Liste:
    12. var list = new ObservableCollection<Foo>
    13. {
    14. new Foo {Garcon = Garcon.Foo1, Name = "Erstens"},
    15. new Foo {Garcon = Garcon.Foo1, Name = "Zweitens"},
    16. new Foo {Garcon = Garcon.Foo2, Name = "Drittens"}
    17. };


    Im View soll es dann so aussehen:
    1. Liste:
    • Foo1 <- selektiert
    • Foo2
    2. Liste:
    • Erstens
    • Zweitens
    Würde man nun Foo2 auswählen, soll das Item mit dem Namen ​Drittens in die zweite Liste.

    Ist sowas irgendwie möglich?
    Mfg
    Vincent

    Also das geht praktisch über die Nummer am ​Foo, oder wie?
    Was ich da jetzt nicht ganz verstehe, in Deinem letzten Codebeispiel hast Du das:
    • 1
    • 1
    • 2
    Soll das so sein oder war das ein Versehen?

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    @Trade
    Meinst du die ausgeschrieben Zahlen als Namen in den Items? Das soll so sein.

    Konkret habe ich eine Liste mit Tracks. Jeder Track hat eine Eigenschaft ​Artist. Alle Artists (aber jeder nur einmal) sollen nun in die linke Liste, die Tracks von diesem Künstler in die rechte (sofern der Künstler ausgewählt wurde):


    Wie du siehst geht es auch schon mit einer Liste (es ist nach Alben sortiert). Ich hätte es aber gerne auf zwei Listen verteilt. (Das mit den Künstlern ist gerade ein Workaround, hat eine unglaublich schlechte Performance und aktualisiert sich nicht mit der "Grundliste")
    Mfg
    Vincent

    Ah, jetzt sehe ich es, soll so sein, weil es ja mehr Titel geben kann.
    Und Du willst es praktisch nicht über eine Liste Deiner Zwischenklasse und deren Properties lösen, sondern direkt über 2 Listen, oder?

    Das mit der Enum ist aber vmtl. ja dann nur ein Beispiel, oder? Weil das ja flexibel laufen muss, wenn das die Artisten anzeigen soll, die kannst Du ja nicht festlegen. :P

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    So, habe jetzt durch eine Menge Tüftelei die Lösung gefunden:
    Die CollectionViewSource kann ja quasi alles, was ich will, jedoch werden die Daten automatisch nur in einer Liste bearbeitet. Weil bei dem CollectionViewSource auch nichts typisiert ist, habe ich jetzt durch jede Menge Breakpoints folgendes herausgefunden:
    Ihr könnte mit Liste #1 einfach an die Groups-Eigenschaft binden. Die Objekte darin besitzen eine Eigenschaft Items. Da dann einfach die zweite Liste dran binden. Fertig.
    Mfg
    Vincent

    ich finde deine Problembeschreibung höchst verworren, aber mir scheint, du hast eine Song-Titel - Liste, willst sie nach Interpret gruppieren, und dann einen Parent-Child-View erstellen, nach der - in der Datenbänkerei nennt man es "Relation": Interpret -> Title.
    Weil so kann man den Begriff "Gruppieren" ganz allgemein auffassen:
    Beim Gruppieren wird eine große flache Liste umgebaut zu einer Hirarchichen Liste von Gruppen, und jede Gruppe enthält dann nur einen Teil der Gesamt-Item.

    Hast du vlt. Lust, deine Lösung zu posten?
    Weil ich hab das Grouping-Feature der CollectionViews noch nie benutzt.

    Generell kannst du auch überlegen, ob du deine Daten nicht von vornherein entsprechend dieser Relation strukturierst.
    @ErfinderDesRades
    Klar:

    ViewModel:

    C#-Quellcode

    1. public ICollectionView ArtistViewSource { get; set; }
    2. //Initalisierung:
    3. public Task Load()
    4. {
    5. if (!_isLoaded)
    6. {
    7. ArtistViewSource = CollectionViewSource.GetDefaultView(Playlist.Tracks);
    8. ArtistViewSource.GroupDescriptions.Add(new PropertyGroupDescription("Artist"));

    (Ich denke es sollte klar sein, dass Playlist.Tracks eine List<Track> ist und dass Track eine Eigenschaft Artist aufweist)

    XAML:

    XML-Quellcode

    1. <Grid>
    2. <Grid.ColumnDefinitions>
    3. <ColumnDefinition Width="300" MinWidth="200" MaxWidth="350"/>
    4. <ColumnDefinition Width="2"/>
    5. <ColumnDefinition Width="*"/>
    6. </Grid.ColumnDefinitions>
    7. <Grid.Resources>
    8. <CollectionViewSource x:Key="AlbumGrouping" Source="{Binding ElementName=ArtistListBox,Path=SelectedItem.Items}">
    9. <CollectionViewSource.GroupDescriptions>
    10. <PropertyGroupDescription PropertyName="Album"/>
    11. </CollectionViewSource.GroupDescriptions>
    12. </CollectionViewSource>
    13. </Grid.Resources>
    14. <ListBox ItemsSource="{Binding ArtistViewSource.Groups}" x:Name="ArtistListBox" />
    15. <GridSplitter HorizontalAlignment="Stretch" Grid.Column="1"/>
    16. <ListBox Grid.Column="2" ItemsSource="{Binding Source={StaticResource AlbumGrouping}}"/>


    Man könnte auch in der letzen ListBox direkt an ArtistListBox.SelectedItem.Items (​{Binding ElementName=ArtistListBox,Path=SelectedItem.Items}) binden, jedoch wollte ich es dann nochmal gruppiert haben (nach Album).

    ErfinderDesRades schrieb:

    ​Generell kannst du auch überlegen, ob du deine Daten nicht von vornherein entsprechend dieser Relation strukturierst.

    Also, dass in meinem Fall Artist eine Liste von Tracks hat? Das ist leider aus mehreren Gründen relativ schwierig:
    Die Anzahl der Tracks ist zB immer anders: Es gibt ja verschiedene Wiedergabelisten, aber die können ja Musik von dem gleichen Künstler beinhalten. Dann müsste man für jede Wiedergabeliste einen neuen Künstler erstellen. Was ich aber als Workaround davor hatte, war ein Dictionary<Artist, List<Track>>. Dann wurde, wenn das aktuell ausgewählte Item verändert wurde, eine neue Liste (von dem Künstler) generiert. Problem davon ist, dass es sich nicht automatisch updatet, wenn irgendetwas dazu kommt und das es relativ kompliziert ist, weil das gleiche dann auch für Alben gemacht werden soll. Ich habe schon überlegt, ob ich mir dafür eine eigene Collection schreibe, welche dann auf das CollectionChanged-Event reagiert.
    Mfg
    Vincent