Partager via


Guide pratique pour personnaliser des cellules et des colonnes dans le contrôle DataGridView Windows Forms en étendant leur comportement et leur apparence

Le DataGridView contrôle fournit plusieurs façons de personnaliser son apparence et son comportement à l’aide de propriétés, d’événements et de classes compagnons. Parfois, vous pouvez avoir des exigences pour vos cellules qui vont au-delà de ce que ces fonctionnalités peuvent fournir. Vous pouvez créer votre propre classe personnalisée DataGridViewCell pour fournir des fonctionnalités étendues.

Vous créez une classe personnalisée DataGridViewCell en dérivant de la DataGridViewCell classe de base ou de l’une de ses classes dérivées. Bien que vous puissiez afficher n’importe quel type de cellule dans n’importe quel type de colonne, vous allez généralement créer une classe personnalisée DataGridViewColumn spécialisée pour afficher votre type de cellule. Les classes de colonne dérivent de DataGridViewColumn ou de l'un de ses types dérivés.

Dans l’exemple de code suivant, vous allez créer une classe de cellule personnalisée appelée DataGridViewRolloverCell qui détecte quand la souris entre et quitte les limites de cellule. Pendant que la souris se trouve dans les limites de la cellule, un rectangle d’ensemble est dessiné. Ce nouveau type dérive de DataGridViewTextBoxCell et se comporte, à tous les autres égards, comme sa classe de base. La classe de colonne complémentaire est appelée DataGridViewRolloverColumn.

Pour utiliser ces classes, créez un formulaire contenant un DataGridView contrôle, ajoutez un ou plusieurs DataGridViewRolloverColumn objets à la Columns collection et remplissez le contrôle avec des lignes contenant des valeurs.

Remarque

Cet exemple ne fonctionnera pas correctement si vous ajoutez des lignes vides. Les lignes vides sont créées, par exemple, lorsque vous ajoutez des lignes au contrôle en définissant la RowCount propriété. Cela est dû au fait que les lignes ajoutées dans ce cas sont automatiquement partagées, ce qui signifie que les objets ne sont pas instanciés tant que DataGridViewRolloverCell vous n’avez pas cliqué sur des cellules individuelles, ce qui entraîne la non-partage des lignes associées.

Étant donné que ce type de personnalisation de cellule nécessite des lignes non partagées, il n’est pas approprié de l’utiliser avec des jeux de données volumineux. Pour plus d’informations sur le partage de lignes, consultez Les meilleures pratiques pour la mise à l’échelle du contrôle DataGridView Windows Forms.

Remarque

Lorsque vous dérivez de DataGridViewCell ou de DataGridViewColumn et ajoutez de nouvelles propriétés à la classe dérivée, veillez à remplacer la méthode Clone pour copier les nouvelles propriétés pendant les opérations de clonage. Vous devez également appeler la méthode Clone de la classe de base afin que les propriétés de la classe de base soient copiées dans la nouvelle cellule ou colonne.

Pour personnaliser des cellules et des colonnes dans le contrôle DataGridView

  1. Dérivez une nouvelle classe de cellule, appelée DataGridViewRolloverCell, du DataGridViewTextBoxCell type.

    public class DataGridViewRolloverCell : DataGridViewTextBoxCell
    {
    
    Public Class DataGridViewRolloverCell
        Inherits DataGridViewTextBoxCell
    
    }
    
    End Class
    
  2. Remplacez la Paint méthode dans la DataGridViewRolloverCell classe. Dans la substitution, appelez d’abord l’implémentation de la classe de base, qui gère les fonctionnalités de la zone de texte hébergée. Utilisez ensuite la méthode du PointToClient contrôle pour transformer la position du curseur (en coordonnées d’écran) en coordonnées de la DataGridView zone cliente. Si les coordonnées de la souris se trouvent dans les limites de la cellule, dessinez le rectangle de l’ensemble.

    protected override void Paint(
        Graphics graphics,
        Rectangle clipBounds,
        Rectangle cellBounds,
        int rowIndex,
        DataGridViewElementStates cellState,
        object value,
        object formattedValue,
        string errorText,
        DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle,
        DataGridViewPaintParts paintParts)
    {
        // Call the base class method to paint the default cell appearance.
        base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
            value, formattedValue, errorText, cellStyle,
            advancedBorderStyle, paintParts);
    
        // Retrieve the client location of the mouse pointer.
        Point cursorPosition =
            this.DataGridView.PointToClient(Cursor.Position);
    
        // If the mouse pointer is over the current cell, draw a custom border.
        if (cellBounds.Contains(cursorPosition))
        {
            Rectangle newRect = new Rectangle(cellBounds.X + 1,
                cellBounds.Y + 1, cellBounds.Width - 4,
                cellBounds.Height - 4);
            graphics.DrawRectangle(Pens.Red, newRect);
        }
    }
    
    Protected Overrides Sub Paint( _
        ByVal graphics As Graphics, _
        ByVal clipBounds As Rectangle, _
        ByVal cellBounds As Rectangle, _
        ByVal rowIndex As Integer, _
        ByVal elementState As DataGridViewElementStates, _
        ByVal value As Object, _
        ByVal formattedValue As Object, _
        ByVal errorText As String, _
        ByVal cellStyle As DataGridViewCellStyle, _
        ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _
        ByVal paintParts As DataGridViewPaintParts)
    
        ' Call the base class method to paint the default cell appearance.
        MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, _
            value, formattedValue, errorText, cellStyle, _
            advancedBorderStyle, paintParts)
    
        ' Retrieve the client location of the mouse pointer.
        Dim cursorPosition As Point = _
            Me.DataGridView.PointToClient(Cursor.Position)
    
        ' If the mouse pointer is over the current cell, draw a custom border.
        If cellBounds.Contains(cursorPosition) Then
            Dim newRect As New Rectangle(cellBounds.X + 1, _
                cellBounds.Y + 1, cellBounds.Width - 4, _
                cellBounds.Height - 4)
            graphics.DrawRectangle(Pens.Red, newRect)
        End If
    
    End Sub
    
  3. Remplacez les méthodes OnMouseEnter et OnMouseLeave dans la classe DataGridViewRolloverCell pour forcer les cellules à se repeindre lorsque le pointeur de la souris entre dans celles-ci ou les quitte.

    // Force the cell to repaint itself when the mouse pointer enters it.
    protected override void OnMouseEnter(int rowIndex)
    {
        this.DataGridView.InvalidateCell(this);
    }
    
    // Force the cell to repaint itself when the mouse pointer leaves it.
    protected override void OnMouseLeave(int rowIndex)
    {
        this.DataGridView.InvalidateCell(this);
    }
    
    ' Force the cell to repaint itself when the mouse pointer enters it.
    Protected Overrides Sub OnMouseEnter(ByVal rowIndex As Integer)
        Me.DataGridView.InvalidateCell(Me)
    End Sub
    
    ' Force the cell to repaint itself when the mouse pointer leaves it.
    Protected Overrides Sub OnMouseLeave(ByVal rowIndex As Integer)
        Me.DataGridView.InvalidateCell(Me)
    End Sub
    
  4. Dérivez une nouvelle classe, appelée DataGridViewRolloverCellColumn, du DataGridViewColumn type. Dans le constructeur, affectez un nouvel DataGridViewRolloverCell objet à sa CellTemplate propriété.

    public class DataGridViewRolloverCellColumn : DataGridViewColumn
    {
        public DataGridViewRolloverCellColumn()
        {
            this.CellTemplate = new DataGridViewRolloverCell();
        }
    }
    
    Public Class DataGridViewRolloverCellColumn
        Inherits DataGridViewColumn
    
        Public Sub New()
            Me.CellTemplate = New DataGridViewRolloverCell()
        End Sub
    
    End Class
    

Exemple :

L’exemple de code complet inclut un petit formulaire de test qui illustre le comportement du type de cellule personnalisé.

using System;
using System.Drawing;
using System.Windows.Forms;

class Form1 : Form
{
    [STAThreadAttribute()]
    public static void Main()
    {
        Application.Run(new Form1());
    }

    public Form1()
    {
        DataGridView dataGridView1 = new DataGridView();
        DataGridViewRolloverCellColumn col =
            new DataGridViewRolloverCellColumn();
        dataGridView1.Columns.Add(col);
        dataGridView1.Rows.Add(new string[] { "" });
        dataGridView1.Rows.Add(new string[] { "" });
        dataGridView1.Rows.Add(new string[] { "" });
        dataGridView1.Rows.Add(new string[] { "" });
        this.Controls.Add(dataGridView1);
        this.Text = "DataGridView rollover-cell demo";
    }
}

public class DataGridViewRolloverCell : DataGridViewTextBoxCell
{
    protected override void Paint(
        Graphics graphics,
        Rectangle clipBounds,
        Rectangle cellBounds,
        int rowIndex,
        DataGridViewElementStates cellState,
        object value,
        object formattedValue,
        string errorText,
        DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle,
        DataGridViewPaintParts paintParts)
    {
        // Call the base class method to paint the default cell appearance.
        base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
            value, formattedValue, errorText, cellStyle,
            advancedBorderStyle, paintParts);

        // Retrieve the client location of the mouse pointer.
        Point cursorPosition =
            this.DataGridView.PointToClient(Cursor.Position);

        // If the mouse pointer is over the current cell, draw a custom border.
        if (cellBounds.Contains(cursorPosition))
        {
            Rectangle newRect = new Rectangle(cellBounds.X + 1,
                cellBounds.Y + 1, cellBounds.Width - 4,
                cellBounds.Height - 4);
            graphics.DrawRectangle(Pens.Red, newRect);
        }
    }

    // Force the cell to repaint itself when the mouse pointer enters it.
    protected override void OnMouseEnter(int rowIndex)
    {
        this.DataGridView.InvalidateCell(this);
    }

    // Force the cell to repaint itself when the mouse pointer leaves it.
    protected override void OnMouseLeave(int rowIndex)
    {
        this.DataGridView.InvalidateCell(this);
    }

}

public class DataGridViewRolloverCellColumn : DataGridViewColumn
{
    public DataGridViewRolloverCellColumn()
    {
        this.CellTemplate = new DataGridViewRolloverCell();
    }
}
Imports System.Drawing
Imports System.Windows.Forms

Class Form1
    Inherits Form

    <STAThreadAttribute()> _
    Public Shared Sub Main()
        Application.Run(New Form1())
    End Sub

    Public Sub New()
        Dim dataGridView1 As New DataGridView()
        Dim col As New DataGridViewRolloverCellColumn()
        dataGridView1.Columns.Add(col)
        dataGridView1.Rows.Add(New String() {""})
        dataGridView1.Rows.Add(New String() {""})
        dataGridView1.Rows.Add(New String() {""})
        dataGridView1.Rows.Add(New String() {""})
        Me.Controls.Add(dataGridView1)
        Me.Text = "DataGridView rollover-cell demo"
    End Sub

End Class

Public Class DataGridViewRolloverCell
    Inherits DataGridViewTextBoxCell

    Protected Overrides Sub Paint( _
        ByVal graphics As Graphics, _
        ByVal clipBounds As Rectangle, _
        ByVal cellBounds As Rectangle, _
        ByVal rowIndex As Integer, _
        ByVal elementState As DataGridViewElementStates, _
        ByVal value As Object, _
        ByVal formattedValue As Object, _
        ByVal errorText As String, _
        ByVal cellStyle As DataGridViewCellStyle, _
        ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _
        ByVal paintParts As DataGridViewPaintParts)

        ' Call the base class method to paint the default cell appearance.
        MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, _
            value, formattedValue, errorText, cellStyle, _
            advancedBorderStyle, paintParts)

        ' Retrieve the client location of the mouse pointer.
        Dim cursorPosition As Point = _
            Me.DataGridView.PointToClient(Cursor.Position)

        ' If the mouse pointer is over the current cell, draw a custom border.
        If cellBounds.Contains(cursorPosition) Then
            Dim newRect As New Rectangle(cellBounds.X + 1, _
                cellBounds.Y + 1, cellBounds.Width - 4, _
                cellBounds.Height - 4)
            graphics.DrawRectangle(Pens.Red, newRect)
        End If

    End Sub

    ' Force the cell to repaint itself when the mouse pointer enters it.
    Protected Overrides Sub OnMouseEnter(ByVal rowIndex As Integer)
        Me.DataGridView.InvalidateCell(Me)
    End Sub

    ' Force the cell to repaint itself when the mouse pointer leaves it.
    Protected Overrides Sub OnMouseLeave(ByVal rowIndex As Integer)
        Me.DataGridView.InvalidateCell(Me)
    End Sub

End Class

Public Class DataGridViewRolloverCellColumn
    Inherits DataGridViewColumn

    Public Sub New()
        Me.CellTemplate = New DataGridViewRolloverCell()
    End Sub

End Class

Compilation du code

Cet exemple nécessite :

  • Références aux assemblys System, System.Windows.Forms et System.Drawing.

Voir aussi