次の方法で共有


方法 : Windows フォーム DataGridView コントロールのセルと列を、それぞれの動作と外観を拡張してカスタマイズする

更新 : 2007 年 11 月

DataGridView コントロールでは、プロパティ、イベント、およびコンパニオン クラスを使用して外観と動作をさまざまな方法でカスタマイズできます。ときとして、これらの要素が提供する以上の機能がセルで必要になる場合があります。独自のカスタム DataGridViewCell クラスを作成すると、拡張機能を提供できます。

カスタム DataGridViewCell クラスを作成するには、DataGridViewCell 基本クラスまたはその派生クラスのいずれかから派生させます。任意の型の列に任意の型のセルを表示できますが、通常は、使用するセル型の表示に特化した独自の DataGridViewColumn クラスを作成します。列クラスは、DataGridViewColumn またはその派生型のいずれかから派生します。

以下のコード例では、セル範囲へのマウスの出入りを検出する DataGridViewRolloverCell という名前のカスタム セル クラスを作成します。マウスがセル範囲に入ると、くぼんだ四角形が描画されます。この新しい型は、DataGridViewTextBoxCell から派生し、他のすべての面では基本クラスと同じように動作します。コンパニオン列クラスは、DataGridViewRolloverColumn と呼ばれます。

これらのクラスを使用するには、DataGridView コントロールを含むフォームを作成し、1 つ以上の DataGridViewRolloverColumn オブジェクトを Columns コレクションに追加し、値を含む行をコントロールに設定します。

7fb61s43.alert_note(ja-jp,VS.90).gifメモ :

この例は、空の行を追加した場合には正しく動作しません。空の行が作成されるのは、たとえば、RowCount プロパティを設定して、行をコントロールに追加した場合です。それは、この場合に追加された行は自動的に共有される、つまり個々のセルをクリックして、関連付けられている行が非共有になるまで DataGridViewRolloverCell オブジェクトがインスタンス化されないためです。

このようなセルのカスタマイズは、非共有行が必要になるため、大型のデータ セットを使用する場合には不適切です。行の共有の詳細については、「Windows フォーム DataGridView コントロールを拡張するための推奨される手順」を参照してください。

7fb61s43.alert_note(ja-jp,VS.90).gifメモ :

DataGridViewCellDataGridViewColumn から派生したクラスに新しいプロパティを追加するときは、Clone メソッドをオーバーライドし、複製操作時に新しいプロパティをコピーする必要があります。また、基本クラスの Clone メソッドを呼び出して、基本クラスのプロパティを新しいセルまたは列にコピーする必要もあります。

DataGridView コントロールのセルと列をカスタマイズするには

  1. DataGridViewTextBoxCell 型から、DataGridViewRolloverCell という新しいセル クラスを派生します。

    Public Class DataGridViewRolloverCell
        Inherits DataGridViewTextBoxCell
    
    
    ...
    
    
    End Class
    
    public class DataGridViewRolloverCell : DataGridViewTextBoxCell
    {
    
    
    ...
    
    
    }
    
  2. DataGridViewRolloverCell クラスの Paint メソッドをオーバーライドします。このオーバーライドでは、ホストされるテキスト ボックス機能を処理する基本クラス実装を最初に呼び出します。次に、コントロールの PointToClient メソッドを使用して、画面座標で示されたカーソル位置を DataGridView クライアント領域の座標に変換します。マウスの座標がセル範囲内の場合、くぼんだ四角形が描画されます。

    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 クラスの OnMouseEnter メソッドと OnMouseLeave メソッドをオーバーライドし、マウス ポインタがセルに出入りしたときにセル自体を再描画させます。

    ' 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 という新しいクラスを派生します。コンストラクタで、新しい 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 で新しいプロジェクトにコードを貼り付けてこの例をビルドすることもできます。 詳細については方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する および方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する および方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する および方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する および方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する.

参照

概念

DataGridView コントロールのアーキテクチャ (Windows フォーム)

Windows フォーム DataGridView コントロールの列型

Windows フォーム DataGridView コントロールを拡張するための推奨される手順

参照

DataGridView

DataGridViewCell

DataGridViewColumn

その他の技術情報

Windows フォーム DataGridView コントロールのカスタマイズ