Autor |
Beitrag |
Trashkid2000
      
Beiträge: 561
Erhaltene Danke: 137
|
Verfasst: Mo 14.11.11 17:47
Hallo liebes Forum,
habe gerade ein riesiges Problem mit der gruppierten Anzeige von Elementen innerhalb eines DataGrid.
ViewModel-technisch sieht es derzeit so aus, dass ich ein ViewModel "LabReport" habe, das eine Liste am ViewModels vom Typ "LabResult" besitzt.
So, also am DataGried liegt als ItemsSource also eine Liste von LabReport-ViewModels an.
Nun sollen also die Werte der LabResults, gruppiert nach dem LabReport angezeigt werden.
Derzeit sieht es so aus:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
| <CollectionViewSource x:Key="LabReports" Source="{Binding LabReports}"> <CollectionViewSource.GroupDescriptions> <PropertyGroupDescription PropertyName="Id"/> </CollectionViewSource.GroupDescriptions> </CollectionViewSource>
<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <Expander IsExpanded="True"> <Expander.Header> <TextBlock Text="{Binding Path=Name}"/> </Expander.Header> <ItemsPresenter/> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource LabReports}}" IsReadOnly="True"> <DataGrid.GroupStyle> <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}"> <GroupStyle.Panel> <ItemsPanelTemplate> <DataGridRowsPresenter /> </ItemsPanelTemplate> </GroupStyle.Panel> </GroupStyle> </DataGrid.GroupStyle> <DataGrid.Columns> <DataGridTextColumn Header="Value" Binding="{Binding Value}"/> </DataGrid.Columns> </DataGrid> | So, das Problem ist nun also, dass ich nirgendswo in der Lage bin, auf die Liste der LabResults innerhalb eines gruppierten Elementes zuzugreifen.
Ich weiß echt nicht, wo ich da ansetzen kann.
Vielen Dank erstmal an alle, die mein Problem durchgelesen haben und mir vielleicht auch weiterhelfen können.
LG, Marko
|
|
Oppi35
      
Beiträge: 95
Erhaltene Danke: 3
|
Verfasst: Mo 14.11.11 18:06
Hi Marko,
enthalten Deine LabResults die Spalten "Id" (Gruppierungsspalte) sowie die Spalte "Value" die Du anzeigen möchtest?
C#-Quelltext 1:
| <DataGridTextColumn Header="Value" Binding="{Binding Value}"/> |
Gruß
Frank
|
|
Trashkid2000 
      
Beiträge: 561
Erhaltene Danke: 137
|
Verfasst: Mo 14.11.11 18:37
Hallo,
also die Property "Id" gehört zum LabReport-ViewModel, und nach der soll auch gruppiert werden (sie ist für jeden Labreport eindeutig). Die Property Value, an die unten gebunden wird, gehört zu einem LabResult-ViewModel. Aber da komm ich ja nicht hin...
Vielleicht ist das mit dem GroupStyle auch totaler Quatsch. Denn die Daten sind ja schon gruppiert. Ich will sie doch bloß innerhalb eines DataGrid anzeigen lassen. Ansonsten wäre das alles kein Problem.
Es wäre auch kein Problem, wenn ich nur eine Liste an LabResults hätte. Denn jedes LabResult kennt seinen LabReport. Da würde das Gruppieren auch klappen. Aber diese Konstellation ist irgendwie zu hoch für mich.
|
|
Oppi35
      
Beiträge: 95
Erhaltene Danke: 3
|
Verfasst: Mo 14.11.11 19:39
Hi Marko,
anbei meine Überarbeitungen. Das ViewModel habe ich mal selbst erstellt:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:
| <Window x:Class="WpfApplication3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:viewmodel="clr-namespace:WpfApplication3" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <viewmodel:LapReportsViewModel x:Key="vm"/> </Window.Resources> <Grid> <Grid.Resources> <CollectionViewSource x:Key="LabReports" Source="{Binding Source={StaticResource vm},Path=LapReports}"> <CollectionViewSource.GroupDescriptions> <PropertyGroupDescription PropertyName="Id"/> </CollectionViewSource.GroupDescriptions> </CollectionViewSource>
<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <Expander IsExpanded="True"> <Expander.Header> <TextBlock Text="{Binding Path=Name}"/> </Expander.Header> <ItemsPresenter/> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> </Grid.Resources>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource LabReports}}" IsReadOnly="True"> <DataGrid.GroupStyle> <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}"> <GroupStyle.Panel> <ItemsPanelTemplate> <DataGridRowsPresenter /> </ItemsPanelTemplate> </GroupStyle.Panel> </GroupStyle> </DataGrid.GroupStyle> <DataGrid.Columns> <DataGridTextColumn Header="Value" Binding="{Binding Value}"/> </DataGrid.Columns> </DataGrid>
</Grid> </Window> |
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| public class LapReportsViewModel { public ObservableCollection<LapResults> LapReports { get; private set; }
public LapReportsViewModel() { LapReports = new ObservableCollection<LapResults>(); LapReports.Add(new LapResults() { Id = 1, Value = "Test1" }); LapReports.Add(new LapResults() { Id = 2, Value = "Test2" }); LapReports.Add(new LapResults() { Id = 2, Value = "Test3" });
} }
public class LapResults { public int Id { get; set; } public string Value { get; set; } } |
Noch ein Hinweis:
Wenn die ID eindeutig ist, musst Du nach ihr nicht gruppieren. Denn das würde bedeuten, dass Du pro Gruppe immer nur einen Eintrag hast. Man gruppiert nach Spalten, deren Werte häufiger vorkommen, um diese dann in einer Gruppe zusammengefasst anzuzeigen. Um die Gruppierung zu zeigen, habe ich die ID 2 in den Testdaten auch doppelt angelegt.
Gruß
Frank
|
|
Trashkid2000 
      
Beiträge: 561
Erhaltene Danke: 137
|
Verfasst: Mo 14.11.11 20:28
Hallo Frank,
erstmal ein großes Danke für Deine Mühe, mir zu helfen.
Leider ist es nicht das, was ich wollte bzw. benötige, um in meinem Problem weiter zu kommen.
Also, ich habe eine Collection von LabReport-ViewModels. Ein VM besitzt z.B. eine Id, ein Datum, ..., und eine Collection von LabResult-ViewModels.
Und genau dort liegt das Problem. Ich benötige einerseits die Daten der LabReports (um sie z.B. in einem Expander als Header anzuzeigen), und ich benötige die Daten der einzelnden LabResult-VM's des Reports. Um sie halt in dem Expander als Content anzuzeigen. Aber das halt für alle Daten innerhalb eines DataGrids.
Das mit dem Gruppieren ist, wie ich auch schon geschrieben habe, vielleicht eh Schwachsinn, da die Daten ja schon gruppiert sind. Aber wie soll ich sie sonst in die DataGrid kriegen?
Aber trotzdem vielen Dank!
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 14.11.11 21:11
Sollten in der CollectionViewSource nicht die Items selbst stehen, gruppiert nach ihrem zugehörigen LabReport? Das ist natürlich etwas umständlich, wenn du bereits so eine hierarchische Gruppierung hast, aber ich nehme einfach mal an, dass es so gedacht ist.
_________________ >λ=
|
|
Oppi35
      
Beiträge: 95
Erhaltene Danke: 3
|
Verfasst: Mo 14.11.11 22:06
Dann ein neuer Versuch:
Ich habe jetzt mal Dein Datagrid gegen eine Treeview ausgetauscht, da ich hier schneller eine hierarchische Sicht erzeugen kann.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71:
| using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel;
namespace WpfApplication3 {
public class MainViewModel { public ObservableCollection<LapReportsViewModel> LapReports { get; private set; }
public MainViewModel() { LapReports = new ObservableCollection<LapReportsViewModel>();
LapResultsViewModel lrvm1 = new LapResultsViewModel() { Value = "Test1" }; LapResultsViewModel lrvm2 = new LapResultsViewModel() { Value = "Test2" }; LapResultsViewModel lrvm3 = new LapResultsViewModel() { Value = "Test2" };
List<LapResultsViewModel> tempListLapResults = new List<LapResultsViewModel>(); tempListLapResults.Add(lrvm1); tempListLapResults.Add(lrvm2); tempListLapResults.Add(lrvm3);
LapReportsViewModel reportsvm = new LapReportsViewModel(tempListLapResults) { ID = 1, Date = "01.01.1950" }; LapReports.Add(reportsvm);
LapResultsViewModel lrvm4 = new LapResultsViewModel() { Value = "Test4" }; LapResultsViewModel lrvm5 = new LapResultsViewModel() { Value = "Test5" }; LapResultsViewModel lrvm6 = new LapResultsViewModel() { Value = "Test5" };
List<LapResultsViewModel> tempListLapResults2 = new List<LapResultsViewModel>(); tempListLapResults2.Add(lrvm4); tempListLapResults2.Add(lrvm5); tempListLapResults2.Add(lrvm6);
LapReportsViewModel reportsvm2 = new LapReportsViewModel(tempListLapResults2) { ID = 2, Date = "01.01.2000" }; LapReports.Add(reportsvm2);
} } public class LapReportsViewModel { public ObservableCollection<LapResultsViewModel> LapResults { get; private set; } public int ID { get; set; } public string Date { get; set; } public LapReportsViewModel(List<LapResultsViewModel> LapResultList) { LapResults = new ObservableCollection<LapResultsViewModel>();
foreach (var item in LapResultList) { LapResults.Add(item); }
} }
public class LapResultsViewModel { public string Value { get; set; } } } |
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| <Window x:Class="WpfApplication3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:viewmodel="clr-namespace:WpfApplication3" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <viewmodel:MainViewModel x:Key="vm"/>
<HierarchicalDataTemplate DataType="{x:Type viewmodel:LapReportsViewModel}" ItemsSource="{Binding LapResults}"> <StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="ID:"/> <TextBlock Text="{Binding ID}" Margin="5,0,5,0"/> <TextBlock Text="Date:"/> <TextBlock Text="{Binding Date}" Margin="5,0,5,0"/> </StackPanel> </StackPanel> </HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type viewmodel:LapResultsViewModel}"> <TextBlock Text="{Binding Value}"/> </DataTemplate> </Window.Resources> <Grid> <Grid.Resources> </Grid.Resources> <TreeView ItemsSource="{Binding Source={StaticResource vm},Path=LapReports}"> </TreeView>
</Grid> </Window> |
Wie die Daten in einem Datagrid hierarchisch dargestellt werden, müsste ich auch erst nachlesen. Aber vielleicht hilfts Dir ja schon so.
Gruß
Frank
|
|
Trashkid2000 
      
Beiträge: 561
Erhaltene Danke: 137
|
Verfasst: Di 15.11.11 07:51
@ Kha: Ja, wenn ich von allen LabReports die LabResults zusammen an die CollectionViewSource packen würde, und dann nach LabReport.Id gruppieren würde, wäre ja alles schön. Aber das Klassendesign ist im Moment ist halt nicht so.
@ Oppi35: Danke nochmal. Werde es mir heute Abend mal genauer anschauen. Mit dem HierarchicalDataTemplate hatte ich mir auch schon mal angeschaut. Wollte halt alles zusammen in einem DataGrid haben, um alles zusammen sortieren zu können...
Muss zugeben, dass ich noch nicht so sehr lange mit WPF arbeite (und wohl auch nicht der große Designer bin). Und da stoße ich oft an meine persönlichen Grenzen.
So sollte es dann mal irgendwie aussehen:
Danke für die Bemühungen.
Einloggen, um Attachments anzusehen!
|
|
Trashkid2000 
      
Beiträge: 561
Erhaltene Danke: 137
|
Verfasst: Di 06.12.11 18:14
Hi,
werde nun nach langem Kopfzerbrechen (und nachdem ich das Problem erstmal verschoben habe) was zu dem Thema schreiben.
Das Grundproblem (also mit dem DataGrid) ist noch nicht gelöst, aber ich habe es jetzt anders umgesetzt.
Nutze nun für die Anzeige ein TreeListView und zeige in der ersten Spalte nun also ein Expander mit ein paar Infos des jeweiligen LabReports an. Also nur ein Datum und die Anzahl der LabResults des jeweiligen Reports. Darunter kommen dann als Details in den anderen Spalten die Werte der jeweiligen LabResults. Das Ganze gelöst dann für jede Spalte mit DataTemplateSelectoren.
Ist an und für sich schon gut. Bloß dass der Expander + Informationen nur in einer Spalte stehen können stört mich ein bisschen. Aber egal, ich gebe mich damit zufrieden.
Muss mich jetzt in dem Projekt, wo eh alles drunter und drüber läuft auch erstmal um andere, wichtigere Sachen kümmern. Und da sich sonst eh keiner um das Projekt kümmert (es interessiert einfach keinen) bin ich auch nicht gewillt, da noch mehr Kraft und (meine Freizeit) reinzustecken.
|
|
|