ListBox Dictionary als ItemsSource

  • WPF

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von Jonas Jelonek.

    ListBox Dictionary als ItemsSource

    Hallo

    Ich schreibe gerade an einem kleinen Programm in WPF. Dabei habe ich eine ListBox auf der GUI, die ich mit Items befüllen will. Diese Items will ich aus einem Dictionary<string,string> beziehen, welches beim Start aus einer Datei geladen werden soll. Kann ich dieses Dictionary<string,string> jetzt irgendwie als Resource definieren damit ich diese dann der ListBox zuweisen kann und daraus die Items erstellen kann?

    Grüße
    Jonas Jelonek
    Ja, leider.

    Das Problem bei dieser Verfahrensweise ist aber, dass ich dann im ItemTemplate nicht Key und Value vom Dictionary einzeln nutzen kann oder mache ich etwas falsch? Ich möchte nämlich den ersten Wert als Farbe in einem Rectangle darstellen lassen und den zweiten dahinter als TextBlock.
    Sicher, dass das ein Dictionary darstellt? Hört sich für mich eher wie eine Datenklasse mit Color- und Text-Eigenschaft, die ein schönes Model abgeben würde und binden kannst du auch ganz einfach daran.
    Geht natürlich auch mit dem Dictionary, du musst nur beachten, dass du KeyValuePair<string, string>-Objekte bekommst. Da kannst du dann schon Key und Value einzeln binden, aber um eine Farbe aus dem String zu konvertieren musst du noch einen Konverter für die Bindung bereit stellen (sollte da vermutlich nen fertigen von MS geben, den du nur noch deklarieren musst).
    Dein Problem sind hier die Generics, die in dieser Form durch XAML nicht unterstütz werden. Du kannst den Typen bei der Deklaration des DataTemplates natürlich einfach weglassen, bekommst dann aber kein Intellisense mehr (das, was EDR als XAML-Bindingpicking bezeichnet):

    XML-Quellcode

    1. <DataTemplate>
    2. <Rectangle Background="{Binding Key}"/>
    3. <TextBlock Text="{Binding Value}"/>
    4. </DataTemplate>
    Beachte, dass dieses Beispiel nicht so laufen wird, du musst noch gewünschtes Layouting hinzufügen.

    Einfacher hättest dus mit einer Datenklasse.
    ObservableCollaction<DeineKlasse> anstelle des Dictionary<string, string>, dann siehts so (ähnlich) aus:

    XML-Quellcode

    1. <DataTemplate DataType="{x:Type local:DeineKlasse}">
    2. <Rectangle Background="{Binding Color}"/>
    3. <TextBlock Text="{Binding Text}"/>
    4. </DataTemplate>
    Die Eigenschaften kannst du ggf. anders benennen. local ist ein Platzhalter für den XML-Namespace, der den CLR-Namespace, in dem sich deine Datenklasse befindet, darstellt, z.B. local="clr-namespace:DeinNamespace".
    Und dann muss ich nur noch in der XAML-Definition der ListBox ItemsSource={Binding myObservableCollection} hinzufuegen und dann noch wie in deinem Codebeispiel in Post #8 den DataType setzen und dann sollte das funktionieren, oder?
    Genau. Die ObservableCollection ist eine ganz normale Collecction, nur mit entsprechender INotifyPropertyChanged-Implementierung für Bindings.
    Aber Anpassen des Templates nicht vergessen, dieses hier wird so direkt nicht kompilieren (Layouting fehlt).
    Ich habe leider noch ein Problem. Wenn ich jetzt im DataTemplate die Properties meiner Klasse nutzen will, werden die nicht angezeigt, sondern immernoch die Properties meines ViewModels. Ich habe alles so gemacht, wie du beschrieben hast.

    XML-Quellcode

    1. <ListBox Name="listBox1" ItemsSource="{Binding colorList}">
    2. <ListBox.ItemTemplate>
    3. <DataTemplate DataType="{x:Type model:Color}">
    4. <Grid>
    5. <Rectangle Height="48" Width="48" Fill="{Binding Color}" VerticalAlignment="Center" HorizontalAlignment="Left"></Rectangle>
    6. <TextBlock Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="60,0,0,0"></TextBlock>
    7. </Grid>
    8. </DataTemplate>
    9. </ListBox.ItemTemplate>
    10. </ListBox>

    C#-Quellcode

    1. public class Color
    2. {
    3. public Color(string name, string code)
    4. {
    5. this.name = name;
    6. if (code.Contains('#'))
    7. { this.code = code; }
    8. }
    9. private string name;
    10. private string code;
    11. public string Name
    12. {
    13. get
    14. { return name; }
    15. }
    16. public string Code
    17. {
    18. get
    19. { return code; }
    20. }
    21. }

    C#-Quellcode

    1. public ObservableCollection<Models.Color> colorList;

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

    Setzt du die colorList im Konstruktor deines Viewmodels? Wenn nicht musst du die als Eigenschaft mit PropertyChanged-Event implementieren.
    Allerdings bin ich durchaus verwirrt, was das fehlende Intellisense angeht, einen Fehler im XAML kann ich nämlich nicht entdecken.