방법: 동작 및 모양을 확장하여 Windows Forms DataGridView 컨트롤에서 셀 및 열 사용자 지정How to: Customize Cells and Columns in the Windows Forms DataGridView Control by Extending Their Behavior and Appearance

DataGridView 컨트롤은 속성, 이벤트 및 도우미 클래스를 통해 모양과 동작을 사용자 지정하는 다양한 방법을 제공합니다.The DataGridView control provides a number of ways to customize its appearance and behavior using properties, events, and companion classes. 경우에 따라 해당 셀에 대해 이러한 기능으로 충족할 수 없는 요구 사항이 있을 수 있습니다.Occasionally, you may have requirements for your cells that go beyond what these features can provide. 고유한 사용자 지정 DataGridViewCell 클래스를 만들어 확장 기능을 제공할 수 있습니다.You can create your own custom DataGridViewCell class to provide extended functionality.

DataGridViewCell 기본 클래스 또는 파생 클래스 중 하나에서 파생시켜 사용자 지정 DataGridViewCell 클래스를 만듭니다.You create a custom DataGridViewCell class by deriving from the DataGridViewCell base class or one of its derived classes. 모든 유형의 열에 모든 유형의 셀을 표시할 수 있지만 일반적으로 셀 형식을 표시하기 위한 사용자 지정 DataGridViewColumn 클래스도 만듭니다.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. 열 클래스는 DataGridViewColumn 또는 파생 형식 중 하나에서 파생됩니다.Column classes derive from DataGridViewColumn or one of its derived types.

다음 코드 예제에서는 마우스가 셀 경계로 들어오고 나갈 때 이를 감지하는 DataGridViewRolloverCell이라는 사용자 지정 셀 클래스를 만듭니다.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. 마우스가 셀 범위 내에 있는 동안 삽입 사각형이 그려집니다.While the mouse is within the cell's bounds, an inset rectangle is drawn. 이 새로운 형식은 DataGridViewTextBoxCell에서 파생되며 다른 모든 측면에서 기본 클래스처럼 동작합니다.This new type derives from DataGridViewTextBoxCell and behaves in all other respects as its base class. 도우미 열 클래스는 DataGridViewRolloverColumn이라고 합니다.The companion column class is called DataGridViewRolloverColumn.

이러한 클래스를 사용하려면 DataGridView 컨트롤이 포함된 폼을 만들고 하나 이상의 DataGridViewRolloverColumn 개체를 Columns 컬렉션에 추가한 다음 값이 포함된 행으로 컨트롤을 채웁니다.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.

참고

빈 행을 추가하는 경우에는 이 예제가 제대로 작동하지 않습니다.This example will not work correctly if you add empty rows. 예를 들어 RowCount 속성을 설정하여 컨트롤에 행을 추가할 때 빈 행이 만들어집니다.Empty rows are created, for example, when you add rows to the control by setting the RowCount property. 이러한 경우에 추가된 행이 자동으로 공유되기 때문이며, 이는 개별 셀을 클릭하여 연결된 행이 공유되지 않도록 할 때까지 DataGridViewRolloverCell 개체가 인스턴스화되지 않음을 의미합니다.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.

이 형식의 셀 사용자 지정에는 공유되지 않는 행이 필요하므로 큰 데이터 집합에 사용하기에 적합하지 않습니다.Because this type of cell customization requires unshared rows, it is not appropriate for use with large data sets. 행 공유에 대 한 자세한 내용은 참조 하세요. Windows Forms DataGridView 컨트롤의 크기 조정에 대 한 모범 사례합니다.For more information about row sharing, see Best Practices for Scaling the Windows Forms DataGridView Control.

참고

DataGridViewCell 또는 DataGridViewColumn에서 파생시키고 파생 클래스에 새 속성을 추가하는 경우 복제 작업 중 새 속성을 복사하도록 Clone 메서드를 재정의해야 합니다.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. 또한 기본 클래스의 속성이 새로운 셀 또는 열에 복사되도록 기본 클래스의 Clone 메서드를 호출해야 합니다.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.

DataGridView 컨트롤에서 셀과 열을 사용자 지정하려면To customize cells and columns in the DataGridView control

  1. DataGridViewTextBoxCell 형식에서 DataGridViewRolloverCell이라는 새로운 셀 클래스를 파생시킵니다.Derive a new cell class, called DataGridViewRolloverCell, from the DataGridViewTextBoxCell type.

    public class DataGridViewRolloverCell : DataGridViewTextBoxCell
    {
    
    Public Class DataGridViewRolloverCell
        Inherits DataGridViewTextBoxCell
    
    }
    
    End Class
    
  2. Paint 클래스에서 DataGridViewRolloverCell 메서드를 재정의합니다.Override the Paint method in the DataGridViewRolloverCell class. 재정의에서 먼저 호스트된 텍스트 상자 기능을 처리하는 기본 클래스 구현을 호출합니다.In the override, first call the base class implementation, which handles the hosted text box functionality. 그런 다음 컨트롤의 PointToClient 메서드를 사용하여 커서 위치(화면 좌표)를 DataGridView 클라이언트 영역 좌표로 변환합니다.Then use the control's PointToClient method to transform the cursor position (in screen coordinates) to the DataGridView client area's coordinates. 마우스 좌표가 셀 범위에 속하는 경우 삽입 사각형을 그립니다.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. DataGridViewRolloverCell 클래스의 OnMouseEnterOnMouseLeave 메서드를 재정의하여 마우스 포인터가 들어가거나 나올 때 셀이 자동으로 그려지도록 강제합니다.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. DataGridViewColumn 형식에서 DataGridViewRolloverCellColumn이라는 새 클래스를 파생시킵니다.Derive a new class, called DataGridViewRolloverCellColumn, from the DataGridViewColumn type. 생성자에서 해당 CellTemplate 속성에 새 DataGridViewRolloverCell 개체를 할당합니다.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
    

예제Example

전체 코드 예제에는 사용자 지정 셀 형식의 동작을 보여 주는 작은 테스트 폼이 포함되어 있습니다.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.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

코드 컴파일Compiling the Code

이 예제에는 다음 사항이 필요합니다.This example requires:

  • System, System.Windows.Forms 및 System.Drawing 어셈블리에 대한 참조References to the System, System.Windows.Forms, and System.Drawing assemblies.

참고자료See also