共用方式為


HOW TO:擴充儲存格和資料行的行為和外觀以自訂 Windows Form DataGridView 控制項中的儲存格和資料行

更新:2007 年 11 月

DataGridView 控制項提供使用屬性、事件和附屬類別自訂外觀和行為的多種方法。有時候儲存格的需求可能會超過這些功能所能提供的範圍。您可以建立自己的自訂 DataGridViewCell 類別以提供擴充功能。

您可以藉由衍生自 DataGridViewCell 基底類別 (Base Class) 或其中一個衍生類別,建立自訂的 DataGridViewCell 類別。雖然可以在任何資料行型別中顯示任何儲存格類型,但您通常還會建立自訂 DataGridViewColumn 類別來專門顯示您的儲存格類型。資料行類別衍生自 DataGridViewColumn 或其中一種衍生型別。

在下列程式碼範例中,您將建立稱為 DataGridViewRolloverCell 的自訂儲存格類別,此類別會偵測滑鼠何時進入或離開儲存格界限。滑鼠位於儲存格的界線內時,會描繪內凹方框。這種新型別是衍生自 DataGridViewTextBoxCell,且在各方面的運作上都和基底型別一樣。附屬資料行型別稱為 DataGridViewRolloverColumn。

若要使用這些類別,請建立包含 DataGridView 控制項的表單、加入一或多個 DataGridViewRolloverColumn 物件至 Columns 集合,以及將包含值的資料列填入控制項。

注意事項:

如果您加入空白資料列,這個範例就無法正確運作。例如,當您藉由設定 RowCount 屬性將資料列加入至控制項時,便會建立空白資料列。這是因為在這種情況下,會自動共用加入的資料列,這意味著該 DataGridViewRolloverCell 物件在您按一下個別儲存格之前並未具現化 (Instantiated),所以會造成關聯的資料列取消共用。

因為這種儲存格自訂需要未共用的資料列,所以不適合和大型資料集搭配使用。如需有關資料列共用的詳細資訊,請參閱縮放 Windows Form DataGridView 控制項的最佳作法

注意事項:

當您從 DataGridViewCellDataGridViewColumn 衍生,並加入新屬性至衍生類別時,請務必覆寫 Clone 方法,以便於複製作業期間複製新屬性。您也應該呼叫基底類別的 Clone 方法,以便複製基底類別的屬性至新儲存格或資料行。

若要自訂 DataGridView 控制項中的儲存格和資料行

  1. DataGridViewTextBoxCell 型別衍生稱為 DataGridViewRolloverCell 的新儲存格類別。

    Public Class DataGridViewRolloverCell
        Inherits DataGridViewTextBoxCell
    
    
    ...
    
    
    End Class
    
    public class DataGridViewRolloverCell : DataGridViewTextBoxCell
    {
    
    
    ...
    
    
    }
    
  2. 覆寫 DataGridViewRolloverCell 類別的 Paint 方法。在覆寫時,先呼叫基底類別實作,這會處理裝載的文字方塊功能。然後使用控制項的 PointToClient 方法,將游標位置 (在螢幕座標上) 轉換為 DataGridView 工作區 (Client Area) 的座標。如果滑鼠座標落在儲存格界限內,描繪內凹方框。

    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. 覆寫 DataGridViewRolloverCell 類別中的 OnMouseEnterOnMouseLeave 方法,以強制儲存格在滑鼠指標在進入或離開時重新自我繪製。

    ' 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. DataGridViewColumn 型別衍生稱為 DataGridViewRolloverCellColumn 的新類別。在建構函式 (Constructor) 中,指派新的 DataGridViewRolloverCell 物件給 CellTemplate 屬性。

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

範例

完整的程式碼範例包含小型測試表單,會示範自訂儲存格類型的行為。

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

編譯程式碼

這項範例需要:

  • System、System.Windows.Forms 和 System.Drawing 組件的參考。

如需從 Visual Basic 或 Visual C# 的命令列建置這個範例的詳細資訊,請參閱從命令列建置 (Visual Basic)使用 csc.exe 建置命令列。您也可以透過將程式碼貼入新的專案,在 Visual Studio 中建置此範例。

請參閱

概念

DataGridView 控制項架構 (Windows Form)

Windows Form DataGridView 控制項中的資料行型別

縮放 Windows Form DataGridView 控制項的最佳作法

參考

DataGridView

DataGridViewCell

DataGridViewColumn

其他資源

自訂 Windows Form DataGridView 控制項