Procedura: personalizzare celle e colonne nel controllo DataGridView di Windows Form estendendone il comportamento e l'aspettoHow to: Customize Cells and Columns in the Windows Forms DataGridView Control by Extending Their Behavior and Appearance

Il controllo DataGridView offre diversi metodi per personalizzare l'aspetto e il comportamento mediante proprietà, eventi e classi correlate.The DataGridView control provides a number of ways to customize its appearance and behavior using properties, events, and companion classes. In alcune situazioni è possibile che i requisiti relativi alle celle non possano essere soddisfatti mediante le funzioni fornite.Occasionally, you may have requirements for your cells that go beyond what these features can provide. In questi casi per estendere le funzionalità è possibile creare una propria classe DataGridViewCell personalizzata.You can create your own custom DataGridViewCell class to provide extended functionality.

La classe DataGridViewCell personalizzata può essere creata derivandola dalla classe di base DataGridViewCell o da una delle relative classi derivate.You create a custom DataGridViewCell class by deriving from the DataGridViewCell base class or one of its derived classes. Sebbene sia possibile visualizzare qualsiasi tipo di cella in qualsiasi tipo di colonna, in genere viene creata anche una classe DataGridViewColumn personalizzata per la visualizzazione del tipo di cella.Although you can display any type of cell in any type of column, you will typically also create a custom DataGridViewColumn class specialized for displaying your cell type. Le classi di colonna derivano da DataGridViewColumn o da uno dei tipi derivati.Column classes derive from DataGridViewColumn or one of its derived types.

Nell'esempio di codice riportato di seguito viene creata la classe di cella personalizzata DataGridViewRolloverCell in grado di rilevare il passaggio in ingresso e in uscita del mouse sui bordi delle celle.In the following code example, you will create a custom cell class called DataGridViewRolloverCell that detects when the mouse enters and leaves the cell boundaries. Quando il mouse è all'interno dei bordi della cella, viene disegnato un rettangolo interno.While the mouse is within the cell's bounds, an inset rectangle is drawn. Poiché questo nuovo tipo è derivato da DataGridViewTextBoxCell, si comporta da tutti gli altri punti di vista come la classe di base.This new type derives from DataGridViewTextBoxCell and behaves in all other respects as its base class. La classe di colonna correlata è DataGridViewRolloverColumn.The companion column class is called DataGridViewRolloverColumn.

Per usare queste classi, creare un form contenente un controllo DataGridView, aggiungere uno o più oggetti DataGridViewRolloverColumn all'insieme Columns e popolare il controllo con righe contenenti valori.To use these classes, create a form containing a DataGridView control, add one or more DataGridViewRolloverColumn objects to the Columns collection, and populate the control with rows containing values.

Nota

L'esempio non funzionerà correttamente se si aggiungono righe vuote.This example will not work correctly if you add empty rows. Le righe vuote vengono create, ad esempio, quando si aggiungono righe al controllo mediante l'impostazione della proprietà RowCount.Empty rows are created, for example, when you add rows to the control by setting the RowCount property. Poiché le righe aggiunte in questo modo vengono automaticamente condivise, non vengono create istanze degli oggetti DataGridViewRolloverCell finché non si selezionano le singole celle, rendendo di conseguenza le righe associate non più condivise.This is because the rows added in this case are automatically shared, which means that DataGridViewRolloverCell objects are not instantiated until you click on individual cells, thereby causing the associated rows to become unshared.

Dato che richiede l'uso di righe non condivise, questo tipo di personalizzazione delle celle non è adatto per insiemi di dati di grandi dimensioni.Because this type of cell customization requires unshared rows, it is not appropriate for use with large data sets. Per ulteriori informazioni sulla condivisione, vedere procedure consigliate per ridimensionare il controllo DataGridView Windows Form.For more information about row sharing, see Best Practices for Scaling the Windows Forms DataGridView Control.

Nota

Quando si deriva dalla classe DataGridViewCell o DataGridViewColumn e si aggiungono nuove proprietà alla classe derivata, accertarsi di eseguire l'override del metodo Clone per copiare le nuove proprietà durante le operazioni di clonazione.When you derive from DataGridViewCell or DataGridViewColumn and add new properties to the derived class, be sure to override the Clone method to copy the new properties during cloning operations. È anche necessario chiamare il metodo Clone della classe base in modo che le proprietà della classe base vengano copiate nella nuova cella o colonna.You should also call the base class's Clone method so that the properties of the base class are copied to the new cell or column.

Per personalizzare celle e colonne nel controllo DataGridViewTo customize cells and columns in the DataGridView control

  1. Derivare una nuova classe di cella, denominata DataGridViewRolloverCell, dal tipo DataGridViewTextBoxCell.Derive a new cell class, called DataGridViewRolloverCell, from the DataGridViewTextBoxCell type.

    public class DataGridViewRolloverCell : DataGridViewTextBoxCell
    {
    
    Public Class DataGridViewRolloverCell
        Inherits DataGridViewTextBoxCell
    
    }
    
    End Class
    
  2. Eseguire l'override del metodo Paint nella classe DataGridViewRolloverCell.Override the Paint method in the DataGridViewRolloverCell class. Eseguire l'override chiamando prima l'implementazione della classe di base, che gestisce la funzionalità della casella di testo inserita,In the override, first call the base class implementation, which handles the hosted text box functionality. quindi usando il metodo PointToClient del controllo per trasformare la posizione del cursore (coordinate dello schermo) nelle coordinate dell'area client DataGridView.Then use the control's PointToClient method to transform the cursor position (in screen coordinates) to the DataGridView client area's coordinates. Se le coordinate del mouse rientrano nei contorni della cella, disegnare il rettangolo interno.If the mouse coordinates fall within the bounds of the cell, draw the inset rectangle.

    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. Eseguire l'override dei metodi OnMouseEnter e OnMouseLeave nella classe DataGridViewRolloverCell per forzare le celle a ridisegnarsi all'ingresso o all'uscita del mouse.Override the OnMouseEnter and OnMouseLeave methods in the DataGridViewRolloverCell class to force cells to repaint themselves when the mouse pointer enters or leaves them.

    // 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. Derivare una nuova classe, denominata DataGridViewRolloverCellColumn, dal tipo DataGridViewColumn.Derive a new class, called DataGridViewRolloverCellColumn, from the DataGridViewColumn type. Nel costruttore assegnare un nuovo oggetto DataGridViewRolloverCell alla relativa proprietà CellTemplate.In the constructor, assign a new DataGridViewRolloverCell object to its CellTemplate property.

    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
    

EsempioExample

L'esempio di codice completo comprende un piccolo form di prova che illustra il comportamento del tipo di cella personalizzato.The complete code example includes a small test form that demonstrates the behavior of the custom cell type.

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
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

Compilazione del codiceCompiling the Code

L'esempio presenta i requisiti seguenti:This example requires:

  • Riferimenti agli assembly System, System.Windows.Forms e System.Drawing.References to the System, System.Windows.Forms, and System.Drawing assemblies.

Per informazioni sulla compilazione di questo esempio dalla riga di comando per Visual Basic o Visual c#, vedere compilazione dalla riga di comando oppure con la creazione della riga di comando csc.exe.For information about building this example from the command line for Visual Basic or Visual C#, see Building from the Command Line or Command-line Building With csc.exe. È anche possibile compilare questo esempio in Visual Studio incollando il codice in un nuovo progetto.You can also build this example in Visual Studio by pasting the code into a new project. Vedere anche Procedura: Compilare ed eseguire un esempio di codice Windows Form completo con Visual Studio.Also see How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio.

Vedere ancheSee Also

DataGridView
DataGridViewCell
DataGridViewColumn
Personalizzazione del controllo DataGridView di Windows FormCustomizing the Windows Forms DataGridView Control
Architettura del controllo DataGridViewDataGridView Control Architecture
Tipi di colonne nel controllo DataGridView di Windows FormColumn Types in the Windows Forms DataGridView Control
Procedure consigliate per ridimensionare il controllo DataGridView di Windows FormBest Practices for Scaling the Windows Forms DataGridView Control