最简单的解决方案是将列设为只读,然后使用按钮列。然后处理CellContentClick
事件DataGridView
以检测按钮点击。
另一种选择是创建基于 DataGridViewButtonColumn 的自定义列。像这样的东西有一点改变来显示单元格的值而不是标签文本。
您也可以通过自定义绘制单元格来实现它,而无需创建任何新的列类型,就像这样。
例子
我的选择是从按钮列派生DataGridView
以获得更好的用户体验,例如在鼠标移动时突出显示按钮。为此,我将更改此答案,该答案显示如何在单个单元格中呈现标签和按钮。在这里,我对其进行了一些更改,以将单元格值显示为标签文本:
using System.Drawing;
using System.Windows.Forms;
public class DataGridViewLookupColumn : DataGridViewButtonColumn
{
public DataGridViewLookupColumn()
{
CellTemplate = new DataGridViewLookupCell();
ButtonText = "...";
}
public string ButtonText { get; set; }
public override object Clone()
{
var c = (DataGridViewLookupColumn)base.Clone();
c.ButtonText = this.ButtonText;
return c;
}
}
public class DataGridViewLookupCell : DataGridViewButtonCell
{
protected override void Paint(Graphics graphics, Rectangle clipBounds,
Rectangle cellBounds, int rowIndex,
DataGridViewElementStates elementState,
object value, object formattedValue, string errorText,
DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
var g = this.DataGridView;
var c = (DataGridViewLookupColumn)this.OwningColumn;
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState,
value, formattedValue, errorText, cellStyle, advancedBorderStyle,
DataGridViewPaintParts.All &
~DataGridViewPaintParts.ContentBackground &
~DataGridViewPaintParts.ContentForeground);
var cellRectangle = g.GetCellDisplayRectangle(c.Index, rowIndex, false);
var buttonRectangle = GetContentBounds(rowIndex);
var textRectangle = new Rectangle(cellRectangle.Location,
new Size(cellRectangle.Width - GetButtonWidth(),
cellRectangle.Height));
buttonRectangle.Offset(cellRectangle.Location);
var alignment = cellStyle.Alignment;
cellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
base.Paint(graphics, clipBounds, buttonRectangle, rowIndex, elementState,
value, c.ButtonText, errorText, cellStyle, advancedBorderStyle,
DataGridViewPaintParts.All &
~DataGridViewPaintParts.Border);
cellStyle.Alignment = alignment;
base.Paint(graphics, clipBounds, textRectangle, rowIndex, elementState,
value, formattedValue, errorText, cellStyle, advancedBorderStyle,
DataGridViewPaintParts.ContentForeground);
}
protected override Rectangle GetContentBounds(Graphics graphics,
DataGridViewCellStyle cellStyle, int rowIndex)
{
var w = GetButtonWidth();
var r = base.GetContentBounds(graphics, cellStyle, rowIndex);
return new Rectangle(r.Right - w, r.Top, w, r.Height);
}
private int GetButtonWidth()
{
var c = (DataGridViewLookupColumn)this.OwningColumn;
var text = c.ButtonText;
return TextRenderer.MeasureText(text, c.DefaultCellStyle.Font).Width
+ 10 /*a bit padding */;
}
}
手柄点击按钮
要处理按钮上的点击,请CellContentClick
像正常一样处理DataGridViewColumnButton
并检查是否e.RowIndex > -1
和e.ColumnIndex == your desired column index
:
void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
//if click is on row header or column header, do nothing.
if(e.RowIndex < 0 || e.ColumnIndex < 0)
return;
//Check if click is on specific column
if( e.ColumnIndex == dataGridView1.Columns["specific column name"].Index)
{
//Put some logic here, for example show a dialog and use result.
}
}