public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// 绑定事件
this.dataGridView1.CellPainting += DataGridView1_CellPainting;
this.dataGridView1.CellClick += DataGridView1_CellClick;
}
private void Form1_Load(object sender, EventArgs e)
{
// 添加三列
dataGridView1.Columns.Add("first", "First");
dataGridView1.Columns.Add("second", "Second");
dataGridView1.Columns.Add("third", "操作"); // 这一列我们将自绘按钮
dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
// 添加15行示例数据
for (int i = 0; i < 15; i++)
{
string first = $"Row{i}";
string second = i % 2 == 0 ? "Even" : "Odd";
dataGridView1.Rows.Add(first, second, ""); // 第三列留空,由我们绘制
}
// 设置第三列不可编辑、居中等
var opCol = dataGridView1.Columns["third"];
opCol.ReadOnly = true;
opCol.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
}
// 判断某行是否应显示操作按钮
private bool ShouldShowButtonsInRow(int rowIndex)
{
if (rowIndex < 0 || rowIndex >= dataGridView1.Rows.Count) return false;
var cellValue = dataGridView1.Rows[rowIndex].Cells["second"].Value?.ToString();
return cellValue == "Even"; // 示例条件:第二列为 "Even"
}
// 定义操作列的左右边距(可调整)
private const int OperationColumnPaddingLeft = 6;
private const int OperationColumnPaddingRight = 6;
private const int OperationColumnPaddingTop = 3;
private const int OperationColumnPaddingBottom = 3;
private const int ButtonSpacing = 10; // 按钮间的间距
// 绘制虚拟按钮(带左右空白和按钮间间距)
private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == dataGridView1.Columns["third"].Index && e.RowIndex >= 0)
{
e.PaintBackground(e.ClipBounds, true);
if (!ShouldShowButtonsInRow(e.RowIndex))
{
e.Handled = true;
return;
}
Rectangle cellRect = e.CellBounds;
// 计算总可用宽度(减去左右边距和按钮间间距)
int usableWidth = cellRect.Width - OperationColumnPaddingLeft - OperationColumnPaddingRight - ButtonSpacing;
// 计算单个按钮的实际宽度
int btnWidth = usableWidth / 2;
Rectangle btn1Rect = new Rectangle(
cellRect.Left + OperationColumnPaddingLeft,
cellRect.Top + OperationColumnPaddingTop,
btnWidth,
cellRect.Height - OperationColumnPaddingTop - OperationColumnPaddingBottom
);
Rectangle btn2Rect = new Rectangle(
cellRect.Left + OperationColumnPaddingLeft + btnWidth + ButtonSpacing,
cellRect.Top + OperationColumnPaddingTop,
btnWidth,
cellRect.Height - OperationColumnPaddingTop - OperationColumnPaddingBottom
);
using (SolidBrush brush = new SolidBrush(SystemColors.Control))
using (Pen pen = new Pen(SystemColors.ControlDark))
{
e.Graphics.FillRectangle(brush, btn1Rect);
e.Graphics.DrawRectangle(pen, btn1Rect.X, btn1Rect.Y, btn1Rect.Width - 1, btn1Rect.Height - 1);
e.Graphics.FillRectangle(brush, btn2Rect);
e.Graphics.DrawRectangle(pen, btn2Rect.X, btn2Rect.Y, btn2Rect.Width - 1, btn2Rect.Height - 1);
}
TextRenderer.DrawText(e.Graphics, "操作1", dataGridView1.Font, btn1Rect, SystemColors.ControlText,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis);
TextRenderer.DrawText(e.Graphics, "操作2", dataGridView1.Font, btn2Rect, SystemColors.ControlText,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis);
e.Handled = true;
}
}
// 处理点击(同样应用相同边距和间距)
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == dataGridView1.Columns["third"].Index && e.RowIndex >= 0)
{
if (!ShouldShowButtonsInRow(e.RowIndex)) return;
DataGridView dgv = sender as DataGridView;
Rectangle cellRect = dgv.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
int usableWidth = cellRect.Width - OperationColumnPaddingLeft - OperationColumnPaddingRight - ButtonSpacing;
int btnWidth = usableWidth / 2;
Rectangle btn1Rect = new Rectangle(
cellRect.Left + OperationColumnPaddingLeft,
cellRect.Top + OperationColumnPaddingTop,
btnWidth,
cellRect.Height - OperationColumnPaddingTop - OperationColumnPaddingBottom
);
Rectangle btn2Rect = new Rectangle(
cellRect.Left + OperationColumnPaddingLeft + btnWidth + ButtonSpacing,
cellRect.Top + OperationColumnPaddingTop,
btnWidth,
cellRect.Height - OperationColumnPaddingTop - OperationColumnPaddingBottom
);
Point clickPoint = dgv.PointToClient(Cursor.Position);
if (btn1Rect.Contains(clickPoint))
{
MessageBox.Show($"操作1 被点击(行 {e.RowIndex})");
}
else if (btn2Rect.Contains(clickPoint))
{
MessageBox.Show($"操作2 被点击(行 {e.RowIndex})");
}
}
}
}