Laden...

Wie kann ich im ViewModel verschachtelte Klassen und Listen an meine View binden?

Erstellt von GeneVorph vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.010 Views
G
GeneVorph Themenstarter:in
180 Beiträge seit 2015
vor 4 Jahren
Wie kann ich im ViewModel verschachtelte Klassen und Listen an meine View binden?

Hallo,

Ich möchte ein Datagrid mit Daten befüllen (MVVM). In meinem ViewModel sieht das dann so aus:


<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding DummyStudents}">
                <DataGrid.Columns >
                    <DataGridTextColumn Header="Nachname" Binding="{Binding LastName}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Vorname" Binding="{Binding PreName}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Klasse" Binding="{Binding ClassLabel}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Bildungsgang" Binding="{Binding EducationType}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Mathematik" Binding="{Binding Subjects.GradeAverageValToStr}"></DataGridTextColumn>
                    
                </DataGrid.Columns>
            </DataGrid>

Soweit funktioniert mein Code - ich bekomme die in 'DummyStudents (eine ObservableCollection<Student>) hinterlegten Objekte angezeigt. Bis auf die 5. Column, denn hier müsste ich auf das Property einer verschachtelten Klasse zugreifen. (public class Student--> List<Subject>Subjects--> hier bit es 10 Einträge, jeder sollte einer extra Column zugeordnet werden.)

Ein Student-Objekt schaut bei mir so aus:



        public string PreName { get; set; }
       
        public string LastName { get; set; }        
              
        public string ClassLabel { get; set; }
     
        public string EducationType { get; set; }
        
        public List<Subject> Subjects { get; set; } = new List<Subject>();

Interessant wird es bei List<Subject> Subjects. Der Typ Subject ist wiederum eine Klasse mit ein paar Properties und wiederum einer List<Grades> Grades (Schulnoten also) usw. Diese sind keine ObservableCollections, sondern eben Lists.

Bisher habe ich es immer so gemacht, dass ich sämtliche für die GUI relevanten Datenfelder in Form gesonderter ObservableCollections oder Properties in meinem ViewModel implementiert hatte.

Meine Frage: gibt es da noch einen anderen Weg? Denn


Binding="{Binding Subjects.GradeAverageValToStr}"

funktioniert nicht - meine ItemsSource ist bereits eine ObservableCollection und 'Subjects' ist eine List<Subject>, die zum Typ 'Student' gehört.

Ich hoffe, ich konnte das Problem einigermaßen genau skizzieren: vereinfacht: was tun, bei verschachtelten Klassen (speziell Objekte, die wieder Listen anderer Objekte bereithalten)?

Gruß
Vorph

4.931 Beiträge seit 2008
vor 4 Jahren

Verstehe ich das richtig, das du je Eintrag in der Subjects-Liste eine neue DataGrid-Spalte erzeugen lassen möchtest?
Dann hast du ein Verständnisproblem (das hat nichts mit dem Typ zu tun), denn durch das Binding werden nicht automatisch neue Spalten erzeugt (sondern es wird nur für die aktuelle Spalte die angegebene Eigenschaft gebunden). Und da Subjects eine Liste ist, gibt es kein Subjects.GradeAverageValToStr, denn du würdest dazu ein konkretes Subject-Objekt benötigen, z.B. Subjects[0].GradeAverageValToStr.

Ich habe zum dynamischen Binden von DataGrid-Spalten folgenden Link gefunden: How to Add Columns to a DataGrid through Binding and Map Its Cell Values (ist aber nicht ganz einfach)

5.657 Beiträge seit 2006
vor 4 Jahren

10 Einträge, jeder sollte einer extra Column zugeordnet werden.

Was spricht dagegen, diese 10 Eigenschaften anstatt der Liste zum ViewModel hinzuzufügen?

Weeks of programming can save you hours of planning

G
GeneVorph Themenstarter:in
180 Beiträge seit 2015
vor 4 Jahren

Hi, und vielen Dank für euere Antworeten!

@Mr.Sparkle

Was spricht dagegen, diese 10 Eigenschaften anstatt der Liste zum ViewModel hinzuzufügen?

Prinzipiell gar nichts - tatsächlich habe ich es jetzt erst einmal so gelöst. Ich nenne das jetzt mal eine "Mediator"-Klasse (kenne den Fachbegriff nicht); eine Klasse, die alle Verschachtelungen als einfache Properties bereitstellt.

@Th69 Nicht ganz ein Verständnisproblem; mir war ja schon klar, dass es so nicht funktioniert - es wäre aber durchaus denkbar gewesen, dass es da eine Art "Workaround" gibt. Übrigens: danke für den Link - dieser ist aber für meine Mini-App "way over the top" 😃

Einstweilen vielen Dank.
Gruß
Vorph