none
WPF -DataGrid - Datenbindung im Code RRS feed

  • Frage

  • Ausgangslage:

    Ich erhalte von einem Webservice verschiedene Datenpakete (asynchron), die aufbereitet und verarbeitet werden müssen. Der letzte Schritt ist die Darstellung der Daten im Programm. Bis jetzt habe ich Windows Form benutzt und kann damit das Problem lösen, will jedoch jetzt auf WPF umsteigen und hier beginnen nun die eigentlichen Probleme.

    Die Daten aus verschiedenen Quellen will ich in einem Datagrid darstellen und die einzelnen Daten zum gegebenen Zeitpunkt aktualisieren. Da jedoch verschiedene Objekte dargestellt werden müssen und diese unterschiedlich viele Elemente enthalten, habe ich keine Lösung in XAML gewählt (hier ist mir die Datenbindung klar), sondern wollte dies im Code regeln.

    Völling naiv versuchte ich dann (nachdem ich die Columns definiert hatte) dem Datagrid ein paar Zeilen (rows) entsprechend der Anzahl der Elemente in dem Objekt hinzuzufügen. Das ist aber anscheinend nicht möglich, da das Datagrid immer eine Art Collection sehen will. Nun bin ich aber nicht weitergekommen und die Hilfe im MSDN war hier keine Hilfe (ich vermisse das System aus VB 2008) und brachte eine Menge Ergebnisse, die sich mit Silverlight, Drittools und anderen befasste (vor allem viel XAML-Code, der mir hier nicht weiterhilft).

    Meine Probleme:

    1. Ich habe bisher nicht verstanden, wie die einzelnen Collections den verschiedenen Columns zugeordnet werden. So wie es aussieht wollen aber bei meinem Programm Werte aus verschiedenen Collections ins Datagrid (ich könnte natürlich noch einen DataTable dazwischenschalten).

    2. Auch Versuche eine Collection in einem Datagrid mit einer Spalte unterzubringen, sind gescheitert. Ich habe zwar DataGrid1.ItemSource = 'Collection' ausprobiert (von simplen Arrays bis generischen Listen), hatte aber nur erreicht, dass entsprechend der Anzahl der Elemente in der Collection nun endlich die entsprechenden Zeilen im Datagrid vorhanden waren, die Zellen aber sind entweder leer (falls AutoColumn = False) oder zeigen die Anzahl der Chars der jeweiligen Elemente. Die Column.Header ist dann passenderweise "Length". 

     

     

    Mittwoch, 15. September 2010 22:27

Antworten

  • Hi Peter,
    wenn Du in einen DataGrid etwas darstellen willst, so ist eine Zeile ein Datenobjekt, dessen Eigenschaften in der Spalte dargestellt werden. Alle anzuzeigenden Datenobjekte (= Zeilen im Grid) werden in einer Liste gehalten, die an die ItemsSource-Eigenschaft gebunden wird.
     
    Aus Deinen Schilderungen scheint es mir am einfachsten, wenn Du eine eigene Klasse für Deine Datenobjekte erstellst. Für jede neue Zeile im Grid erzeugst Du eine neue Instanz, füllst diese mit Deinen darzustellenden Daten und fügst die Instanz einer Liste hinzu, die an ItemsSource gebunden ist.

    --
    Viele Gruesse
    Peter

    • Als Antwort markiert Peter Simpel Donnerstag, 16. September 2010 15:48
    Donnerstag, 16. September 2010 04:50
  • Hi Peter,
    Deine Klasse "Baum" hat keine Eigenschaften für die Anzeige. Au�?erdem hat Deine "quelle2" keine Datenobjekte mit anzuzeigenden Eigeschaften. �?ndere das mal und es funktioniert.
     

    --
    Viele Gruesse
    Peter

    • Als Antwort markiert Peter Simpel Donnerstag, 16. September 2010 15:40
    Donnerstag, 16. September 2010 14:19

Alle Antworten

  • Hi Peter,
    wenn Du in einen DataGrid etwas darstellen willst, so ist eine Zeile ein Datenobjekt, dessen Eigenschaften in der Spalte dargestellt werden. Alle anzuzeigenden Datenobjekte (= Zeilen im Grid) werden in einer Liste gehalten, die an die ItemsSource-Eigenschaft gebunden wird.
     
    Aus Deinen Schilderungen scheint es mir am einfachsten, wenn Du eine eigene Klasse für Deine Datenobjekte erstellst. Für jede neue Zeile im Grid erzeugst Du eine neue Instanz, füllst diese mit Deinen darzustellenden Daten und fügst die Instanz einer Liste hinzu, die an ItemsSource gebunden ist.

    --
    Viele Gruesse
    Peter

    • Als Antwort markiert Peter Simpel Donnerstag, 16. September 2010 15:48
    Donnerstag, 16. September 2010 04:50
  • Ich bin noch nicht wirklich weitergekommen. Um die Probleme mal zu veranschaulichen habe ich eine kleine Testapplikation geschrieben: Auf dem MainWindow habe ich ein Datagrid und eine Listbox sowie eine Checkbox gesetzt. Beim Datagrid habe ich die Eigenschaft AutoGenerateColumn = "True" gesetzt. (Code siehe unten)

    Beim Laden des Programms erhalte ich im DataGrid eine Spalte mit 3 Zeilen, die alle leer sind. Die Listbox zeigt folgenden Inhalt an:

    Databindung_Test2.Baum

    Databindung_Test2.Baum

    Databindung_Test2.Baum

    {NewItemPlaceholder}

    (Datenbindung_Test2 = Programmname)

    Wenn ich jetzt ein Häkchen setze in der Checkbox ändert sich der Inhalt iM Datagrid ColumnHeader = "Length" und die drei Zeilen enthalten die Einträge: 5,5,5 . In der Listbox sind die drei Baumarten dagegen korrekt aufgeführt.

     

    Class MainWindow 
    
      Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        Dim quelle As New List(Of Baum)
    
        Dim a As New Baum
        a.Baumart = "Eiche"
        quelle.Add(a)
        a.Baumart = "Birke"
        quelle.Add(a)
        a.Baumart = "Linde"
        quelle.Add(a)
    
        DataGrid1.ItemsSource = quelle
        ListBox1.ItemsSource = quelle
    
      End Sub
    
      Private Sub CheckBox1_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles CheckBox1.Checked
        Dim quelle2 As New List(Of String)
    
        quelle2.Add("Eiche")
        quelle2.Add("Birke")
        quelle2.Add("Linde")
    
        DataGrid1.ItemsSource = quelle2
        ListBox1.ItemsSource = quelle2
      End Sub
    End Class
    
    Public Class Baum
      Public Baumart As String
    End Class
    Donnerstag, 16. September 2010 11:09
  • Hi Peter,
    Deine Klasse "Baum" hat keine Eigenschaften für die Anzeige. Au�?erdem hat Deine "quelle2" keine Datenobjekte mit anzuzeigenden Eigeschaften. �?ndere das mal und es funktioniert.
     

    --
    Viele Gruesse
    Peter

    • Als Antwort markiert Peter Simpel Donnerstag, 16. September 2010 15:40
    Donnerstag, 16. September 2010 14:19
  • EIn public Feld reicht also nicht aus, um die Eigenschaften anzuzeigen. Ich habe daher den Code wie folgt geändert:

     

    Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        Dim quelle As New List(Of Baum)
    
        Dim a As New Baum
        a.Baumart = "Eiche"
        a.Laenge = 350
        quelle.Add(a)
        Dim b As New Baum
        b.Baumart = "Birke"
        b.Laenge = 400
        quelle.Add(b)
        Dim c As New Baum
        c.Baumart = "Linde"
        c.Laenge = 350
        quelle.Add(c)
    
        DataGrid1.ItemsSource = quelle
        ListBox1.ItemsSource = quelle
    
      End Sub
    
    Public Class Baum
      Dim _Baumart As String
      Dim _Laenge As Integer
    
      Property Baumart As String
        Get
          Return _Baumart
        End Get
        Set(ByVal value As String)
          _Baumart = value
        End Set
      End Property
    
      Property Laenge As String
        Get
          Return _Laenge
        End Get
        Set(ByVal value As String)
          _Laenge = value
        End Set
      End Property
    End Class

    Die Listbox- Anzeige ist unverändert. in "Pro WPF in C# 2010" von M. MacDonald wird auf S.612 das Problem erörtert und als Lösung vorgeschlagen:

    a) Nutzen der DisplayMemberPath - Property

    b) Override die ToString() - Methode

    c) Einsatz von DataTemplates

    Das Buch ist übrigens auch für VB und WPF sehr gut nutzbar, sofern man die "kleinen" Unterschiede zwischen VB und C# berücksichtigt (beide Sprachen sind ja quasi Geschwister).

     

    Donnerstag, 16. September 2010 15:48
  •  
    EIn public Feld reicht also nicht aus, um die Eigenschaften anzuzeigen.
     
    Hi Peter,
    was hat ein public Feld mit einer Eigenschaft zu tun? Wie sool man Deine Aussage verstehen?
    Ich habe daher den Code wie folgt geändert:
     
    Funktioniert er jetzt?
    ...
        ListBox1.ItemsSource = quelle

    ...

    Die Listbox- Anzeige ist unverändert. in "Pro WPF in C# 2010" von M. MacDonald wird auf S.612 das Problem erörtert und als Lösung vorgeschlagen:

    a) Nutzen der DisplayMemberPath - Property

    Die ListBox zeigt nur eine Eigenschaft an. Diese muss der ListBox mitgelteilt werden.

    b) Override die ToString() - Methode

    Wenn die Mitteilung der Eigenschaft fehlt, wird ToString genutzt.

    c) Einsatz von DataTemplates

    Damit ist es möglich mehrere Eigenschaften anzuzeigen.

    Das Buch ist übrigens auch für VB und WPF sehr gut nutzbar, sofern man die "kleinen" Unterschiede zwischen VB und C# berücksichtigt (beide Sprachen sind ja quasi Geschwister).

    C#.NET und VB.NET sind völlig unterschiedlich bezüglich Sprachsyntax und nur insofern vergleichbar, als es Basiskonstrukte gibt, die in Basic seit vielen Jahren genutzt werden und jetzt auch in C# genutzt werden.

    Ansonsten sind beide Sprachen bezüglich des benötigten Stromes aus der Steckdose für die Arbeit des PC identisch : - )

    --
    Viele Gruesse
    Peter

    Donnerstag, 16. September 2010 20:00