Bonjour à tous !
Après une requête sur une base de données, je récupère une liste de Bon de Travail (BT). Dans chaque BT se trouve une liste de PM. Un PM est un Tuple de la forme "Nom PM", "Valeur PM".
J'obtiens donc une structure de la forme suivante:
LstBT
|BT1
||NuméroBT
||LstPM
|||NomPM1BT1,ValeurPM1BT1
|||NomPM2BT1,ValeurPM2BT1
|BT2
||NuméroBT
||LstPM
|||NomPM1BT2,ValeurPM1BT2
|||NomPM2BT2,ValeurPM2BT2
...
Le but est d'afficher dans un DataGrid la liste des BT en plaçant l'ensemble des Noms de PM en colonnes de celui-ci et, bien entendu, afficher la Valeur du PM dans ce tableau.
Pour répondre à ce besoin, je parcours l'ensemble des LstPM dans ma LstBT pour en extraire tous les noms PM. Je génère ainsi en code behind mes colonnes dans mon dataGrid qui contient des colonnes "fixes":
XAML
Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 <!-- Liste des interventions--> <Custom:DataGrid x:Name="dataGridBT" AutoGenerateColumns="False" CanUserSortColumns="True" IsReadOnly="True" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.LstBT}"> <Custom:DataGrid.Columns> <Custom:DataGridTextColumn Header="Numéro BT" Binding="{Binding Code}" /> <Custom:DataGridTextColumn Header="Type Station" Binding="{Binding TypeStation}" /> <Custom:DataGridTextColumn Header="Secteur" Binding="{Binding CodeSite}" /> <Custom:DataGridTextColumn Header="Bassin/Site" Binding="{Binding Bassin}" /> <Custom:DataGridTextColumn Header="Sous-Bassin" Binding="{Binding SousBassin}" /> <Custom:DataGridTextColumn Header="Code Station" Binding="{Binding CodeEmplacement}" /> <Custom:DataGridTextColumn Header="Nom Station" Binding="{Binding NomStation}" /> <Custom:DataGridTextColumn Header="Société BT" Binding="{Binding CodeSociete}" /> <Custom:DataGridTextColumn Header="Commentaire BT" Binding="{Binding LongueDescription}"/> </Custom:DataGrid.Columns> </Custom:DataGrid>
Code-Behind
Mes colonnes se créent bien dans mon DataGrid, sans problèmes, avec les bons Headers. Viens ensuite le problème majeur: placer correctement les valeurs des PM sur les bons BT et au bon endroit.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 /// <summary> /// Injection des colonnes dynamiquement dans le datagrid concerné /// </summary> /// <param name="sender">Le datagrid</param> /// <param name="lstNomPM">La liste des noms de PM à exploiter</param> private void SetColumnInDataGrid(List<string> lstNomPM) { //Recherche du DataGrid dans lequel insérer les colonnes ContentPresenter cp = FindVisualChild<ContentPresenter>(this.Onglets); DataGrid dgBT = cp.ContentTemplate.FindName("dataGridBT", cp) as DataGrid; // headers a ajouter List<string> headers = new List<string>(); for (int i = 0; i < lstNomPM.Count; i++) { bool aAjouter = true; foreach(DataGridColumn column in dgBT.Columns) { if (column.Header.Equals(lstNomPM[i])) { aAjouter = false; break; } } if (aAjouter) { headers.Add(lstNomPM[i]); } } //Ajouter les colonnes for (int i = 0; i < headers.Count; i++) { var col = new DataGridTextColumn(); col.Header = headers[i]; col.IsReadOnly = true; col.CanUserSort = true; dgBT.Columns.Add(col); } dgBT.UpdateLayout(); }
Je ne sais pas si cela est possible en Binding directement, il me semble que non. Du coup je suis parti sur une solution de remplissage "à la volée" un peu sale:
Code-behind
Au lancement de l'écran, les données sont bien placées sur les bons BT.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 /// <summary> /// Remplit le datagrid où les colonnes sont générées /// </summary> /// <param name="observableCollection"></param> private void SetValueInDataGrid(ObservableCollection<AdapterTaWorkOrder> lstWorkOrder, List<string> lstNomPM) { //Recherche du DataGrid ContentPresenter cp = FindVisualChild<ContentPresenter>(this.Onglets); DataGrid dgBT = cp.ContentTemplate.FindName("dataGridBT", cp) as DataGrid; //Parcours des BT et des lignes du datagrid for (int iOnRow = 0; iOnRow < lstWorkOrder.Count; iOnRow++) { //Ligne courante var currRow = (DataGridRow)dgBT.ItemContainerGenerator.ContainerFromIndex(iOnRow); //BT courant (correspondant à la ligne) [TODO A terme: test sur numéro de BT] var currBT = lstBT[iOnRow]; //Parcours des PM du BT courant pour injection dans le DataGrid foreach (var pm in currBT.LstPM) { //Parcours des colonnes pour y injecter les valeurs //NB: Il y a 9 colonnes "fixes" déclarées dans le xaml, les suivantes étant générées dynamiquement // On saute donc celles-ci (+ 9) for (int iOnCol = 0; iOnCol < (lstNomPM.Count + 9); iOnCol++) { //Colonne courante var currCol = dgBT.Columns[iOnCol]; //Si le header parcouru correspond au nom du PM courant if (currCol.Header.ToString() == pm.Item1) { // On sélectionne la cellule qui va bien var currCell = new DataGridCellInfo(dgBT.Items[iOnRow], dgBT.Columns[iOnCol]); FrameworkElement ele = dgBT.Columns[iOnCol].GetCellContent(dgBT.Items[iOnRow]); if (ele != null) { FrameworkElement eleCell = ele.Parent as DataGridCell; DataGridCell dgCell = (DataGridCell)eleCell; dgCell.Content = pm.Item2; } } } } } dgWO.UpdateLayout(); }
Toutefois, plusieurs problèmes comportementaux (qui m'ont amené a poster ici):
- La sélection de ligne du tableau est impossible (j'entends par là, juste le surlignage de la ligne cliquée). j'ai tenté en rajoutant des propriétés de mode de sélection (DataGridSelectionUnit à FullRow) mais rien y fait: lorsque je click sur une ligne, elle n'est pas sélectionnée (du moins visuellement)
- Le tri sur les colonnes fixes donne des trucs vraiment étrange: les valeurs des colonnes générées disparaissent. J'ai tenté de supprimer-réajouter les colonnes-reremplir les données, mais rien n'y fait: les valeurs des PM ne sont pas visible. Toutefois, un simple click à n'importe quel endroit du DataGrid le replace dans son état nominal: les colonnes générées et les valeurs placées au bon endroit. C'est à n'y rien comprendre
Donc voila, j'aimerai savoir tout d'abord si un Binding est impossible dans mon cas (i.e. binder une liste de liste) et si je m'y prend bien pour positionner mes valeurs de PM dans mon DataGrid. En fait, toutes remarques sur ma démarche peut m'être utiles
Merci d'avance !![]()
Partager