Gewusst wie: Anpassen von Zellen und Spalten im DataGridView-Steuerelement in Windows Forms durch Erweitern des Aussehens und Verhaltens

Aktualisiert: November 2007

Das DataGridView-Steuerelement bietet eine Reihe von Möglichkeiten, sein Aussehen und Verhalten mithilfe von Eigenschaften, Ereignissen und Assistentenklassen anzupassen. Gelegentlich haben Sie möglicherweise Anforderungen an die Zellen, die über das hinausgehen, was diese Features bereitstellen können. Sie können Ihre eigene benutzerdefinierte DataGridViewCell-Klasse erstellen, um erweiterte Funktionalität bereitzustellen.

Sie erstellen eine benutzerdefinierte DataGridViewCell-Klasse, indem Sie von der DataGridViewCell-Basisklasse oder eine ihrer abgeleiteten Klassen ableiten. Auch wenn Sie in jeder Spalte jeden Zellentyp anzeigen können, erstellen Sie normalerweise eine benutzerdefinierte DataGridViewColumn-Klasse speziell zum Anzeigen des Zellentyps. Spaltenklassen leiten sich von DataGridViewColumn oder einem davon abgeleiteten Typ ab.

Im folgenden Codebeispiel erstellen Sie eine benutzerdefinierte Zellenklasse namens DataGridViewRolloverCell, die erkennt, wann sich der Mauszeiger innerhalb bzw. außerhalb der Zellenumgrenzung befindet. Wenn sich der Mauszeiger innerhalb der Zellenumgrenzungen befindet, wird ein abgesenktes Rechteck gezeichnet. Dieser neue Typ leitet sich von DataGridViewTextBoxCell ab und verhält sich in jeder anderen Hinsicht wie seine Basisklasse. Die Assistentenspaltenklasse lautet DataGridViewRolloverColumn.

Um diese Klassen zu verwenden, erstellen Sie ein Formular mit einem DataGridView-Steuerelement, fügen Sie ein oder mehrere DataGridViewRolloverColumn-Objekte zur Columns-Auflistung hinzu, und füllen Sie das Steuerelement mit Zeilen, die Werte enthalten.

Hinweis:

Dieses Beispiel funktioniert nicht ordnungsgemäß, wenn Sie leere Zeilen hinzufügen. Leere Zeilen werden beispielsweise erstellt, wenn Sie dem Steuerelement Zeilen hinzufügen, indem Sie die RowCount-Eigenschaft festlegen. Das liegt daran, dass die in diesem Fall hinzugefügten Zeilen automatisch freigegeben werden, d. h. DataGridViewRolloverCell-Objekte werden erst instanziiert, wenn Sie auf einzelne Zellen klicken und somit die Freigabe der zugeordneten Zeilen aufheben.

Da bei dieser Art Zellenanpassung nicht freigegebene Zeilen benötigt werden, eignet sie sich nicht für große Datasets. Weitere Informationen über das Freigeben von Zeilen finden Sie unter Empfohlene Vorgehensweisen für das Skalieren des DataGridView-Steuerelements in Windows Forms.

Hinweis:

Wenn Sie von DataGridViewCell oder DataGridViewColumn ableiten und der abgeleiteten Klasse neue Eigenschaften hinzufügen, müssen Sie die Clone-Methode überschreiben, um die neuen Eigenschaften bei Klonvorgängen zu kopieren. Sie sollten stets die Clone-Methode der Basisklasse aufrufen, sodass die Eigenschaften der Basisklasse in die neue Zelle oder Spalte kopiert werden.

So passen Sie Zellen und Spalten im DataGridView-Steuerelement an

  1. Leiten Sie eine neue Zellenklasse namens DataGridViewRolloverCell vom DataGridViewTextBoxCell-Typ ab.

    Public Class DataGridViewRolloverCell
        Inherits DataGridViewTextBoxCell
    
    
    ...
    
    
    End Class
    
    public class DataGridViewRolloverCell : DataGridViewTextBoxCell
    {
    
    
    ...
    
    
    }
    
  2. Überschreiben Sie die Paint-Methode in der DataGridViewRolloverCell-Klasse. Rufen Sie in der Überschreibung zunächst die Basisklassenimplementierung auf, die die gehostete Textfeldfunktionalität behandelt. Verwenden Sie anschließend die PointToClient-Methode des Steuerelements, um die Cursorposition (in Bildschirmkoordinaten) in die Koordinaten des DataGridView-Clientbereichs umzuwandeln. Wenn die Mauskoordinaten innerhalb der Zellenumgrenzung liegen, zeichnen Sie das abgesenkte Rechteck.

    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. Überschreiben Sie die OnMouseEnter-Methode und OnMouseLeave-Methode in der DataGridViewRolloverCell-Klasse, um Zellen dazu zu zwingen, sich selbst neu zu zeichnen, wenn der Mauszeiger darüber bewegt wird.

    ' 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. Leiten Sie eine neue Klasse namens DataGridViewRolloverCellColumn vom DataGridViewColumn-Typ ab. Weisen Sie im Konstruktor ein neues DataGridViewRolloverCell-Objekt seiner CellTemplate-Eigenschaft zu.

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

Beispiel

Das vollständige Codebeispiel umfasst ein kleines Testformular, das das Verhalten des benutzerdefinierten Zellentyps zeigt.

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

Kompilieren des Codes

Für dieses Beispiel sind erforderlich:

  • Verweise auf die Assemblys System, System.Drawing und System.Windows.Forms.

Informationen zum Erstellen dieses Beispiels über die Befehlszeile für Visual Basic oder Visual C# finden Sie unter Erstellen von der Befehlszeile aus (Visual Basic) oder unter Erstellen über die Befehlszeile mit csc.exe. Sie können dieses Beispiel auch in Visual Studio erstellen, indem Sie den Code in ein neues Projekt einfügen.

Siehe auch

Konzepte

Architektur des DataGridView-Steuerelements (Windows Forms)

Spaltentypen im DataGridView-Steuerelement in Windows Forms

Empfohlene Vorgehensweisen für das Skalieren des DataGridView-Steuerelements in Windows Forms

Referenz

DataGridView

DataGridViewCell

DataGridViewColumn

Weitere Ressourcen

Anpassen des DataGridView-Steuerelements von Windows Forms