Самое простое решение - сделать колонку доступной только для чтения, а затем использовать колонку с кнопками. Затем обработайте CellContentClick
событие DataGridView
, чтобы обнаружить нажатия кнопки.
Другой вариант - создание настраиваемого столбца на основе DataGridViewButtonColumn. Что-то вроде этого с небольшим изменением показывает значение ячейки вместо текста метки.
Вы также можете достичь этого, не создавая новый тип столбца, просто закрасив ячейку, например, .
Пример
Мой выбор основан на столбце DataGridView
кнопки для лучшего взаимодействия с пользователем, например, выделение кнопки при перемещении мыши. Для этого я изменю ответ , который показывает, как отображать метку и кнопку в одной ячейке. Здесь я немного его изменяю, чтобы отображать значения ячеек в виде текста метки:
![enter image description here](https://i.stack.imgur.com/nxJnM.png)
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.
}
}