Como: Personalizar células e colunas em Windows Forms DataGridView controle, estendendo seu comportamento e aparência

The DataGridView controle fornece várias maneiras de personalizar sua aparência e comportamento usando propriedades, eventos e complementar classes. Ocasionalmente, talvez você tenha requisitos para as células que vão além do que podem fornecer esses recursos.Você pode criar seus próprios personalizado DataGridViewCell classe para fornecer funcionalidade estendida.

Criar um personalizada DataGridViewCell classe derivando da DataGridViewCell classe base ou uma de suas classes derivadas. Embora você possa exibir qualquer tipo de célula em qualquer tipo de coluna, você irá normalmente também criar um personalizado DataGridViewColumn classe especializada para exibir o tipo de célula. Classes de coluna derivar DataGridViewColumn ou um de seus tipos derivados.

O exemplo de código a seguir, você irá criar uma classe de célula personalizado chamado DataGridViewRolloverCell que detecta quando o mouse entra e sai os limites da célula. Enquanto o mouse está dentro dos limites da célula, um retângulo de baixo-relevo é desenhado.Esse novo tipo deriva de DataGridViewTextBoxCell e se comporta em todos sistema autônomo outros aspectos sistema autônomo sua classe base. A classe de coluna complementar é chamada DataGridViewRolloverColumn.

Para usar essas classes, crie um formulário que contém um DataGridView controle, adicione um ou mais DataGridViewRolloverColumn objetos para o Columns coleção e popular o controle com linhas que contêm valores.

Observação:

Este exemplo não funcionará corretamente se você adicionar linhas vazias.Linhas vazias são criadas, por exemplo, quando você adiciona linhas no controle definindo a RowCount propriedade. Isso ocorre porque as linhas adicionadas nesse caso são compartilhadas automaticamente, que significa que DataGridViewRolloverCell objetos não são instanciados até você clicar em células individuais, causando assim as linhas associadas para se tornar não compartilhado.

Como esse tipo de personalização de célula requer linhas não compartilhadas, não é apropriado para uso com grandes conjuntos de dados.Para obter mais informações sobre o compartilhamento de linha, consulte Práticas recomendadas para escala o controle DataGridView do Windows Forms.

Observação:

Quando você deriva de DataGridViewCell ou DataGridViewColumn e adicionar novas propriedades à classe derivada, certifique-se de substituir o Clone método para copiar as novas propriedades durante operações de clonagem. Você também deve chamar Clone método para que as propriedades da classe base são copiadas para a nova célula ou coluna.

Para personalizar as células e colunas no controle DataGridView

  1. Derivar uma nova classe de célula, chamada DataGridViewRolloverCell, da DataGridViewTextBoxCell Digite.

    Public Class DataGridViewRolloverCell
        Inherits DataGridViewTextBoxCell
    
    
    ...
    
    
    End Class
    
    public class DataGridViewRolloverCell : DataGridViewTextBoxCell
    {
    
    
    ...
    
    
    }
    
  2. Substituir o Paint método na DataGridViewRolloverCell classe. Na substituir, primeiro chame a implementação da classe base, que controla a funcionalidade de caixa de texto hospedado.Em seguida, use PointToClient método para transformar a posição do cursor (em coordenadas de tela) para o DataGridView coordenadas da área de cliente. Se as coordenadas do mouse estejam dentro dos limites da célula, desenhe o retângulo de baixo-relevo.

    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
    
    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);
        }
    }
    
  3. Substituir o OnMouseEnter e OnMouseLeave métodos de DataGridViewRolloverCell classe forçar células para redesenhar próprios quando o ponteiro do mouse entra ou sai-los.

    ' 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
    
    // 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);
    }
    
  4. Derivar uma nova classe, chamada DataGridViewRolloverCellColumn, da DataGridViewColumn Digite. No construtor, atribua um novo DataGridViewRolloverCell objeto para o seu CellTemplate propriedade.

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

Exemplo

O exemplo de código completo inclui um formulário de teste pequena que demonstra o comportamento do tipo de célula personalizado.

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
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();
    }
}

Compilando o código

Este exemplo requer:

  • Referências aos assemblies do sistema, System.Windows.Forms e System.desenho.

Para obter informações sobre como criar este exemplo a partir da linha de comando para Visual Basic ou Visual C#, consulte Criando a partir da linha de comando (Visual Basic) ou Linha de comando criando com csc.exe.Você também pode construir este exemplo no Visual Studio colando o código em um novo projeto.

Consulte também

Conceitos

Arquitetura de DataGridView controle (Windows Forms)

Tipos de coluna no Windows Forms DataGridView controle

Práticas recomendadas para escala o controle DataGridView do Windows Forms

Referência

DataGridView

DataGridViewCell

DataGridViewColumn

Outros recursos

Personalizando o Windows Forms DataGridView controle