방법: 동작 및 모양을 확장하여 Windows Forms DataGridView 컨트롤에서 셀 및 열 사용자 지정
DataGridView 컨트롤은 속성, 이벤트 및 도우미 클래스를 통해 모양과 동작을 사용자 지정하는 다양한 방법을 제공합니다. 경우에 따라 해당 셀에 대해 이러한 기능으로 충족할 수 없는 요구 사항이 있을 수 있습니다. 고유한 사용자 지정 DataGridViewCell 클래스를 만들어 확장 기능을 제공할 수 있습니다.
DataGridViewCell 기본 클래스 또는 파생 클래스 중 하나에서 파생시켜 사용자 지정 DataGridViewCell 클래스를 만듭니다. 모든 유형의 열에 모든 유형의 셀을 표시할 수 있지만 일반적으로 셀 형식을 표시하기 위한 사용자 지정 DataGridViewColumn 클래스도 만듭니다. 열 클래스는 DataGridViewColumn 또는 파생 형식 중 하나에서 파생됩니다.
다음 코드 예제에서는 마우스가 셀 경계로 들어오고 나갈 때 이를 감지하는 DataGridViewRolloverCell
이라는 사용자 지정 셀 클래스를 만듭니다. 마우스가 셀 범위 내에 있는 동안 삽입 사각형이 그려집니다. 이 새로운 형식은 DataGridViewTextBoxCell에서 파생되며 다른 모든 측면에서 기본 클래스처럼 동작합니다. 도우미 열 클래스는 DataGridViewRolloverColumn
이라고 합니다.
이러한 클래스를 사용하려면 DataGridView 컨트롤이 포함된 폼을 만들고 하나 이상의 DataGridViewRolloverColumn
개체를 Columns 컬렉션에 추가한 다음 값이 포함된 행으로 컨트롤을 채웁니다.
참고
빈 행을 추가하는 경우에는 이 예제가 제대로 작동하지 않습니다. 예를 들어 RowCount 속성을 설정하여 컨트롤에 행을 추가할 때 빈 행이 만들어집니다. 이러한 경우에 추가된 행이 자동으로 공유되기 때문이며, 이는 개별 셀을 클릭하여 연결된 행이 공유되지 않도록 할 때까지 DataGridViewRolloverCell
개체가 인스턴스화되지 않음을 의미합니다.
이 형식의 셀 사용자 지정에는 공유되지 않는 행이 필요하므로 큰 데이터 집합에 사용하기에 적합하지 않습니다. 행 공유에 대한 자세한 내용은 Windows Forms DataGridView 컨트롤의 크기를 조정하는 최선의 방법을 참조하세요.
참고
DataGridViewCell 또는 DataGridViewColumn에서 파생시키고 파생 클래스에 새 속성을 추가하는 경우 복제 작업 중 새 속성을 복사하도록 Clone
메서드를 재정의해야 합니다. 또한 기본 클래스의 속성이 새로운 셀 또는 열에 복사되도록 기본 클래스의 Clone
메서드를 호출해야 합니다.
DataGridView 컨트롤에서 셀과 열을 사용자 지정하려면
DataGridViewTextBoxCell 형식에서
DataGridViewRolloverCell
이라는 새로운 셀 클래스를 파생시킵니다.public class DataGridViewRolloverCell : DataGridViewTextBoxCell {
Public Class DataGridViewRolloverCell Inherits DataGridViewTextBoxCell
}
End Class
Paint 클래스에서
DataGridViewRolloverCell
메서드를 재정의합니다. 재정의에서 먼저 호스트된 텍스트 상자 기능을 처리하는 기본 클래스 구현을 호출합니다. 그런 다음 컨트롤의 PointToClient 메서드를 사용하여 커서 위치(화면 좌표)를 DataGridView 클라이언트 영역 좌표로 변환합니다. 마우스 좌표가 셀 범위에 속하는 경우 삽입 사각형을 그립니다.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
DataGridViewRolloverCell
클래스의 OnMouseEnter 및 OnMouseLeave 메서드를 재정의하여 마우스 포인터가 들어가거나 나올 때 셀이 자동으로 그려지도록 강제합니다.// 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
DataGridViewColumn 형식에서
DataGridViewRolloverCellColumn
이라는 새 클래스를 파생시킵니다. 생성자에서 해당 CellTemplate 속성에 새DataGridViewRolloverCell
개체를 할당합니다.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
예제
전체 코드 예제에는 사용자 지정 셀 형식의 동작을 보여 주는 작은 테스트 폼이 포함되어 있습니다.
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
코드 컴파일
이 예제에는 다음 사항이 필요합니다.
- System, System.Windows.Forms 및 System.Drawing 어셈블리에 대한 참조
참고 항목
.NET Desktop feedback
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기