Nardo26
Messages postés37Date d'inscriptionsamedi 13 janvier 2018StatutMembreDernière intervention 1 mars 2021
-
Modifié le 21 mai 2019 à 21:39
Nardo26
Messages postés37Date d'inscriptionsamedi 13 janvier 2018StatutMembreDernière intervention 1 mars 2021
-
22 mai 2019 à 11:41
Bonsoir,
Je rencontre un petit pb : après avoir affecté des DataTables dans des GridView, j'édite le style des lignes en fct de certains critères.
Malheureusement ces modifs n'ont pas l'air d'être prises en considération.
J'ai écrit un petit bout de code pour montrer mon soucis (ce code est complet et peut être exécuté tel quel)...
Il y a 2 choses qui me chiffonne :
1- Dans le Form_load : après avoir affecté la DataTable en source, la méthode count du GridView me renvoie 0. Dans le form_load, les modifs dans les cellules ou sur le style, ne sont pas prises en compte.
2- Une fois que le timer se déclenche, la page active est mise à jour mais pas les autres. Si on clique par exemple sur la page 5 avant le timer, la page 5 est rafraichie MAIS aussi la page 1. Les autres pages restent avec le texte en noir...
Public Class Form1
Private Clock As New Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim TabCtrl As New TabControl With {.Padding = New Point(14, 10), .Dock = DockStyle.Fill}
AddHandler Clock.Tick, AddressOf ClockEvent
For i = 1 To 5 ' Création de 5 pages
Dim p As New TabPage With {.Text = "Page_" + i.ToString}
With p
Dim dtaTable As New DataTable("Essai" + i.ToString)
Dim dtaView As New DataGridView With {.Dock = DockStyle.Fill, .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill}
For j = 1 To 3
dtaTable.Columns.Add("Col_" + j.ToString)
Next j
For k = 0 To 15
dtaTable.Rows.Add("Nom " + i.ToString + k.ToString, "Prenom " + i.ToString + k.ToString, Now())
Next k
dtaView.DataSource = dtaTable
' Ceci ne fonctionne pas car dtaView.Rows.Count = 0... pourquoi ?
' Par contre, dans la methode du timer, rows.count = 17 dans chaque grid
For Each row As DataGridViewRow In dtaView.Rows
If (row.Index And 1) = 1 Then row.DefaultCellStyle.ForeColor = Color.Red
Next
p.Controls.Add(dtaView)
End With
TabCtrl.TabPages.Add(p) ' Ajout de la page
Next
Me.Controls.Add(TabCtrl) ' Ajout du TabControl dans le form
' on lance le timer pour le test
Clock.Interval = 3000
Clock.Start()
End Sub
Private Sub ClockEvent()
Dim dtaView As DataGridView
Dim NbPage As Integer = CType(Me.Controls.Item(0), TabControl).TabPages.Count
Me.Text = "NbPage:" + NbPage.ToString + " Nb de lignes dans les GridView : "
' On passe toutes les lignes de chaque grid en rouge
For i = 0 To NbPage - 1
dtaView = CType(Me.Controls.Item(0), TabControl).TabPages(i).Controls(0)
For Each row As DataGridViewRow In dtaView.Rows
row.DefaultCellStyle.ForeColor = Color.Red
Next
' le nb de ligne dans les grid est correct alors qu'il ne l'etait pas dans le form_load
Me.Text += dtaView.Rows.Count.ToString + ","
Next i
Clock.Stop()
End Sub
End Class
vb95
Messages postés3406Date d'inscriptionsamedi 11 janvier 2014StatutContributeurDernière intervention20 mars 2023165 Modifié le 22 mai 2019 à 03:26
Bonjour
Pour ton premier problème voici le code corrigé pour le Form_Load
Il faut ajouter TabCtrl tout de suite dans la Form sinon tu ne peux point ajouter la DataGridView dans la Page ni ensuite la Page dans TabCtrl car dans ce cas TabCtrl n'est pas présent sur la Form
Et si la DatagridView n'est pas présente sur la Form elle ne se remplit pas avec le DataSource et tu ne peux accéder à son nombre de lignes
Par contre lorsque tu ajoutes TabCtrl à la Form à la ligne 32 de ton premier code tout fonctionne et s'affiche sur la Form mais l'affichage une ligne sur deux en rouge n'a pas pu se faire vu une DataGridview vide et non affichée avant cette ligne 32
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim TabCtrl As New TabControl With {.Padding = New Point(14, 10), .Dock = DockStyle.Fill}
Me.Controls.Add(TabCtrl) ' Ajout du TabControl dans le form tout de suite
AddHandler Clock.Tick, AddressOf ClockEvent
For i = 1 To 5 ' Création de 5 pages
Dim p As New TabPage With {.Text = "Page_" + i.ToString}
With p
Dim dtaTable As New DataTable("Essai" + i.ToString)
Dim dtaView As New DataGridView With {.Dock = DockStyle.Fill, .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill}
For j = 1 To 3
dtaTable.Columns.Add("Col_" + j.ToString)
Next j
For k = 0 To 15
dtaTable.Rows.Add("Nom " + i.ToString + k.ToString, "Prenom " + i.ToString + k.ToString, Now())
Next k
dtaView.DataSource = dtaTable
.Controls.Add(dtaView) ' ajout de la DataGridView dans TabPage
TabCtrl.TabPages.Add(p) ' Ajout de la page dans Tabcontrol
For Each row As DataGridViewRow In dtaView.Rows
If (row.Index And 1) = 1 Then row.DefaultCellStyle.ForeColor = Color.Red
Next
End With
Next
' on lance le timer pour le test
Clock.Interval = 3000
Clock.Start()
End Sub
Pour le second souci je ne te comprends pas ! Peux-tu expliquer plus clairement ?
Pour moi les 5 pages sont en rouge
Nardo26
Messages postés37Date d'inscriptionsamedi 13 janvier 2018StatutMembreDernière intervention 1 mars 2021 22 mai 2019 à 08:59
Bonjour,
Désolé pour ma réponse longue... ;)
L'ajout du TabControl en début du form load "corrige" en parti les deux problèmes.
Mais je n'en comprend pas la raison.
Si je lance ton code tel quel : je ne passe pas dans la boucle du formLoad puisque la DGV est vide (chose que je ne comprend pas puisqu'il y a eu un Fill juste avant) mais le Timer affecte bien toutes les pages.
"Il faut ajouter TabCtrl tout de suite dans la Form sinon tu ne peux point ajouter la DataGridView dans la Page ni ensuite la Page dans TabCtrl"
La construction des différents objets me parait correcte puisqu'au final, tous les DGV s'affichent avec le contenu des DataTable au moment du fill. Donc L'ajout est bien réalisé.
Chronologiquement je créé une page, je créé une DGV que je modifie puis que j'insère dans la page. Puis cette page je la rajoute à mon TabCtrl. Au final, j'ajoute ce "paquet" d'objets à ma Form. Où se trouve l'erreur dans mon raisonnement ?
Pour avancer, par analogie avec ce que tu me proposes vb95 au sujet du TabControl , j'ai fais de même pour les TabPage et les DataGridView. J'ai inséré ces objets de suite après les avoir instancié et avant de les manipuler.
En faisant cela, pour toutes les TabPages qui sont créées, je passe bien dans la boucle du form_load qui me modifie le style des lignes (c'est déjà un net progrès).
Mais à l'affichage, je n'ai que la 1ere PageTab qui s'affiche correctement.
Ci-joint le code modifié en tenant compte de tes remarques vb95.
Si je ne démarre pas le timer, je me retrouve avec seulement la 1ere TabPage de correcte. Les autres restent noires.
Si je démarre le timer : même punition, seule la 1ere TabPage passe en rouge (et éventuellement la TabPage sélectionnée avant déclenchement) sont mises à jour.
Là, je suis vraiment embrouillé : pourquoi ton code vb95 fonctionne (dans le cadre du timer) et pas le dernier que j'ai fais ?
Public Class Form1
Private Clock As New Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim TabCtrl As New TabControl With {.Padding = New Point(14, 10), .Dock = DockStyle.Fill}
Me.Controls.Add(TabCtrl) ' Ajout du TabControl dans le form
For i = 1 To 5 ' Création de 5 pages
Dim p As New TabPage With {.Text = "Page_" + i.ToString}
TabCtrl.TabPages.Add(p) ' Ajout de la page
With p
Dim dtaTable As New DataTable("Essai" + i.ToString)
Dim dtaView As New DataGridView With {.Dock = DockStyle.Fill, .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill}
p.Controls.Add(dtaView)
dtaView.DataSource = dtaTable
For j = 1 To 3
dtaTable.Columns.Add("Col_" + j.ToString)
Next j
For k = 0 To 15
dtaTable.Rows.Add("Nom " + i.ToString + k.ToString, "Prenom " + i.ToString + k.ToString, Now())
Next k
' Cette fois-ci, je passe bien dans cette boucle :
For Each row As DataGridViewRow In dtaView.Rows
If (row.Index And 1) = 1 Then row.DefaultCellStyle.ForeColor = Color.Red
row.Cells.Item(0).Value = "toto"
Next
End With
Next
' on lance le timer pour le test
AddHandler Clock.Tick, AddressOf ClockEvent
Clock.Interval = 3000
Clock.Start()
End Sub
Private Sub ClockEvent()
Dim dtaView As DataGridView
Dim NbPage As Integer = CType(Me.Controls.Item(0), TabControl).TabPages.Count
Me.Text = "NbPage:" + NbPage.ToString + " Nb de lignes dans les GridView : "
' On passe toutes les lignes de chaque grid en rouge
For i = 0 To NbPage - 1
dtaView = CType(Me.Controls.Item(0), TabControl).TabPages(i).Controls(0)
For Each row As DataGridViewRow In dtaView.Rows
row.DefaultCellStyle.ForeColor = Color.Red
Next
' le nb de ligne dans les grid est correct alors qu'il ne l'etait pas dans le form_load
Me.Text += dtaView.Rows.Count.ToString + ","
Next i
Clock.Stop()
End Sub
End Class
Note : si j'inverse les lignes 14 et 15, cela ne fonctionne plus… donc l'ordre parait important mais je n'en saisi pas la logique. :/
Nardo26
Messages postés37Date d'inscriptionsamedi 13 janvier 2018StatutMembreDernière intervention 1 mars 2021 22 mai 2019 à 09:12
Ce qui est encore plus troublant c'est que si je rajoute cette ligne dans la boucle du Timer, toutes les pages sont bien affectées (mais pas le ForeColor)
Nardo26
Messages postés37Date d'inscriptionsamedi 13 janvier 2018StatutMembreDernière intervention 1 mars 2021 Modifié le 22 mai 2019 à 11:43
J'ai fini par trouver grâce à vb95 qui m'a mis sur la bonne piste.
il me reste plus qu'à "digérer" ce que cela implique…
(surtout le fait qu'il faut absolument ajouter le TabControl au tout début)
Merci vb95 !
La solution :
Public Class Form1
Private Clock As New Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim TabCtrl As New TabControl With {.Padding = New Point(14, 10), .Dock = DockStyle.Fill}
Me.Controls.Add(TabCtrl) ' Ajout du TabControl dans le form
For i As Integer = 1 To 5 ' Création de 5 pages
' Cet ordre est très important
Dim dtaView As DataGridView = New DataGridView With {.Dock = DockStyle.Fill, .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill}
Dim tPage As New TabPage With {.Text = "Page_" + i.ToString}
tPage.Controls.Add(dtaView)
TabCtrl.TabPages.Add(tPage) ' Ajout de la page
Dim dtaTable As DataTable = New DataTable("Essai" + i.ToString)
For j As Integer = 1 To 3
dtaTable.Columns.Add("Col_" + j.ToString)
Next j
For k As Integer = 0 To 15
dtaTable.Rows.Add("Nom " + i.ToString + k.ToString, "Prenom " + i.ToString + k.ToString, Now())
Next k
With dtaView
.DataSource = dtaTable
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
.AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(192, 255, 192) ' pour le fun
End With
For Each row As DataGridViewRow In dtaView.Rows
If (row.Index Mod 3) = 0 Then row.DefaultCellStyle.ForeColor = Color.Red
row.Cells.Item(0).Value = "toto"
Next
dtaTable = Nothing
dtaView = Nothing
Next
' on lance le timer pour le test
AddHandler Clock.Tick, AddressOf ClockEvent
Clock.Interval = 5000
Clock.Start()
End Sub
Private Sub ClockEvent()
For i As Integer = 0 To CType(Me.Controls(0), TabControl).TabPages.Count - 1
RafrDGV(i)
Next
Clock.Stop()
End Sub
Private Sub RafrDGV(Optional ByVal Id As Integer = -1)
Dim dtaView As DataGridView
With CType(Me.Controls(0), TabControl) ' on pointe sur le tabControl
If Id = -1 Then Id = .SelectedIndex
dtaView = .TabPages(Id).Controls(0)
For Each row As DataGridViewRow In dtaView.Rows
If (row.Index Mod 3) = 0 Then ' un test quelconque pour l'exemple
row.DefaultCellStyle.ForeColor = Color.Red
row.Cells.Item(0).Value = (Id + 1).ToString + "_titi"
End If
Next
End With
End Sub
End Class