foliv57
Messages postés420Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention15 juillet 2014
-
12 mai 2011 à 10:31
foliv57
Messages postés420Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention15 juillet 2014
-
13 mai 2011 à 10:02
Bonjour à tous,
Je suis face à un problème qui me rend un peut fou.
Je me suis fait une classe "DataGridViewCustomColumnHeaderCell" qui hérite de "DataGridViewColumnHeaderCell" toute simple, qui ne fait qu'afficher un petit carré de couleur en haut à gauche de l'en-tête.
La couleur du carré doit changer à chaque Paint de l'en-tête.
C'est la ou mon problème commence. Si par exemple mon DataGridView contient 4 colonnes. Si je survole avec la sourie la 4ème colonne, l'évènement paint de toutes les en-tetes de colonnes est bien exécuté, mais seul celui de la colonne 4 est rafraichi à l'écran.
J'ai pensais à une histoire de limite de region du graphics lors du paint, mais à priori ce n'est pas le cas, car la région de dessin comprend toute la largeur du DataGridView. J'ai l'impression que c'est le DataGridView qui bloque le rafraichissement uniquement sur une seule en-tête. Le problème est que je ne peut pas demander à ce dernier de rafraichir toutes les en-tetes dans le paint d'une d'elles, car je vous laisse imaginer que ceci provoque une boucle infinie.
Je m'en remet donc à vos lumières, si quelqu'un a déjà rencontré le problème.
Merci d'avance.
Voici donc la classe qui défini mon en-tete custom et une colonne de textboxs avec ce type d'en-tete.
Public Class DataGridViewCustomColumnHeaderCell
Inherits DataGridViewColumnHeaderCell
Private rColor As Color
Protected Overrides Sub Paint(ByVal graphics As System.Drawing.Graphics, ByVal clipBounds As System.Drawing.Rectangle, ByVal cellBounds As System.Drawing.Rectangle, ByVal rowIndex As Integer, ByVal dataGridViewElementState As System.Windows.Forms.DataGridViewElementStates, ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal advancedBorderStyle As System.Windows.Forms.DataGridViewAdvancedBorderStyle, ByVal paintParts As System.Windows.Forms.DataGridViewPaintParts)
MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
'Inversion de la couleur
rColor = CType(IIf(rColor.Equals(Color.Red), Color.RoyalBlue, Color.Red), Color)
'Création du rectangle à dessiner
Dim rect As Rectangle = cellBounds
rect.X += 5
rect.Y += 5
rect.Width = 10
rect.Height = 10
'Dessinne le rectangle
graphics.FillRectangle(New SolidBrush(rColor), rect)
'Affichage d'un message sur paint de l'en-tete de colonne 2
If (Me.ColumnIndex = 1) Then
Console.WriteLine("{0}.{1} Le carré de la colonne 2 doit être {2}", Now.ToLongTimeString, Now.Millisecond, rColor.ToString)
End If
End Sub
End Class
Public Class DataGridViewCustomTextBoxColumn
Inherits DataGridViewTextBoxColumn
Public Sub New()
MyBase.New()
Me.HeaderCell = New DataGridViewCustomColumnHeaderCell
End Sub
Public Sub New(ByVal name As String, ByVal headerText As String)
Me.New()
Me.Name = name
Me.HeaderText = headerText
End Sub
End Class
Et le code pour ajouter 4 colonnes à un datagridview sur load d'une form
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
With Me.DataGridView1
.Columns.Add(New DataGridViewCustomTextBoxColumn("col1", "Colonne 1"))
.Columns.Add(New DataGridViewCustomTextBoxColumn("col2", "Colonne 2"))
.Columns.Add(New DataGridViewCustomTextBoxColumn("col3", "Colonne 3"))
.Columns.Add(New DataGridViewCustomTextBoxColumn("col4", "Colonne 4"))
For j As Integer = 0 To .Columns.Count - 1
.Columns(j).Width = 100
Next
.ColumnHeadersHeight = Me.DataGridView1.ColumnHeadersHeight * 2
.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomRight
End With
End Sub
En affichant les messages de la console on remarque bien que lors du passage de la sourie sur l'en-tete de la colonne 4, la couleur affiché dans le message sur paint de la colonne 2 ne correspond pas à la couleur visible à l'écran.
A voir également:
Probleme de Paint sur un DataGridViewColumnHeaderCell
foliv57
Messages postés420Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention15 juillet 20149 13 mai 2011 à 10:02
Problème résolu.
Voici donc la solution pour les personnes ayant le même souci de partage d'éléments entre colonnes.
Le problème vient bien du DataGridView. C'est lui qui défini quelle région doit être redessinée. Donc, dans mon exemple, même si l'évènement paint est bien lancé pour chaque colonne, seul la zone de l'en-tete de colonne survolée par la sourie est rafraichie.
Ceci est bien visible en tracant l'évènement Paint du DataGridView, le paramètre e.ClipRectangle et limité à la taille de l'en-tete survolée. C'est donc ce paramètre qui empêche les autres en-tetes d'etre redessinées. N'ayant pas touver comment redéfinir ce ClipRectangle, j'ai donc utilisé la technique ci-dessous.
Public Class DataGridViewCustomColumnHeaderCell
Inherits DataGridViewColumnHeaderCell
'Couleur partagée entre les colonnes
Private Shared _rColor As Color
'Evenement de changement de couleur partagé pour informer toutes les colonnes
Private Shared Event ColorChange As EventHandler
'Zone du carré de couleur
Private _rBounds As Rectangle
'Changement de couleur
Public Property rColor As Color
Get
Return _rColor
End Get
Set(ByVal value As Color)
_rColor = value
'Informe toutes les colonnes du changement
RaiseEvent ColorChange(Me, EventArgs.Empty)
End Set
End Property
'Nouvelle instance
Public Sub New()
'Initilaisation de la couleur du carré
_rColor = Color.RoyalBlue
'Abonement à l'évènement de changement de couleur
AddHandler DataGridViewCustomColumnHeaderCell.ColorChange, AddressOf Me_ColorChange
End Sub
Private Sub Me_ColorChange(ByVal sender As Object, ByVal e As EventArgs)
If (Me.DataGridView IsNot Nothing) Then
'Demande au datagridview de mettre à jour l'affichage du carré
Me.DataGridView.Invalidate(_rBounds)
End If
End Sub
'Définition des évènements qui changent la couleur
Protected Overrides Sub OnMouseEnter(ByVal rowIndex As Integer)
MyBase.OnMouseEnter(rowIndex)
'Inversion de la couleur
rColor = CType(IIf(_rColor.Equals(Color.Red), Color.RoyalBlue, Color.Red), Color)
End Sub
Protected Overrides Sub OnMouseLeave(ByVal rowIndex As Integer)
MyBase.OnMouseLeave(rowIndex)
'Inversion de la couleur
rColor = CType(IIf(_rColor.Equals(Color.Red), Color.RoyalBlue, Color.Red), Color)
End Sub
Protected Overrides Sub Paint(ByVal graphics As System.Drawing.Graphics, ByVal clipBounds As System.Drawing.Rectangle, ByVal cellBounds As System.Drawing.Rectangle, ByVal rowIndex As Integer, ByVal dataGridViewElementState As System.Windows.Forms.DataGridViewElementStates, ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal advancedBorderStyle As System.Windows.Forms.DataGridViewAdvancedBorderStyle, ByVal paintParts As System.Windows.Forms.DataGridViewPaintParts)
MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
'Création du rectangle à dessiner
_rBounds = cellBounds
_rBounds.X += 5
_rBounds.Y += 5
_rBounds.Width = 10
_rBounds.Height = 10
'Dessinne le rectangle
graphics.FillRectangle(New SolidBrush(_rColor), _rBounds)
End Sub
End Class