Существует 3 основных столпа для нового типа столбца:
DataGridViewColumn
отвечает за свойства, которые вы задали в режиме конструктора в редакторе столбцов элемента управления. DataGridViewCell
отвечает за внешний вид ячейки.Он отображает значение и другие детали рисования в ячейке и инициализирует элемент управления для редактирования (если столбец имеет какой-либо элемент управления для редактирования). DataGridViewEditingControl
отвечает за редактирование значения ячейки.
При создании нового столбца вы можете наследовать от DataGridViewColumn
или одного из его производных классов.Также при создании новой ячейки для столбца вы можете получить из DataGridViewCell
или одного из его производных классов.Кроме того, при создании нового элемента управления для редактирования вы можете извлечь из одного из существующих элементов управления для редактирования или начать с создания класса управления и реализации интерфейса IDataGridViewEditingControl
.
Имейте в виду, что элемент управления редактирования будетбыть показано только в ячейке редактирования.Остальные ячейки показывают, что вы визуализируете в методе рисования ячейки.
Пример
Здесь, в этом посте, я поделился примером рисования пользовательской ячейкисодержащий ярлык и кнопку.Я не создал элемент управления для редактирования, потому что для этого примера мы можем получить производные от DataGridViewButtonColumn
и DataGridViewButtonCell
без необходимости создания элемента управления для редактирования.Мы просто добавляем некоторые свойства в столбец и меняем логику рисования и переопределяем OnContentClick
, чтобы отобразить контекстное меню, например:
![enter image description here](https://i.stack.imgur.com/pjZJF.png)
Пользовательский столбец имеетLabelText
и ButtonText
свойства.При нажатии на часть кнопки отображается ContextMenuStrip
, который вы присвоили соответствующему свойству.
Примечание: Это всего лишь пример, и в зависимости от требований выможет потребоваться изменить свойства, логику рендеринга и способ отображения меню или что-либо еще.Но я думаю, что это хорошая отправная точка.
Вот код:
using System.Drawing;
using System.Windows.Forms;
public class DataGridViewAllocationControlColumn : DataGridViewButtonColumn
{
public DataGridViewAllocationControlColumn()
{
this.CellTemplate = new DataGridViewAllocationControlCell();
}
public string LabelText { get; set; }
public string ButtonText { get; set; }
public override object Clone()
{
var c = (DataGridViewAllocationControlColumn)base.Clone();
c.LabelText = this.LabelText;
c.ButtonText = this.ButtonText;
return c;
}
}
public class DataGridViewAllocationControlCell : 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 = (DataGridViewAllocationControlColumn)this.OwningColumn;
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState,
value, formattedValue, errorText, cellStyle, advancedBorderStyle,
DataGridViewPaintParts.All &
~DataGridViewPaintParts.ContentBackground &
~DataGridViewPaintParts.ContentForeground);
var r1 = g.GetCellDisplayRectangle(c.Index, rowIndex, false);
var r2 = GetContentBounds(rowIndex);
var r3 = new Rectangle(r1.Location, new Size(GetLabelWidth(), r1.Height));
r2.Offset(r1.Location);
base.Paint(graphics, clipBounds, r2, rowIndex, elementState,
value, c.ButtonText, errorText, cellStyle, advancedBorderStyle,
DataGridViewPaintParts.All);
TextRenderer.DrawText(graphics, c.LabelText, cellStyle.Font,
r3, cellStyle.ForeColor);
}
protected override Rectangle GetContentBounds(Graphics graphics,
DataGridViewCellStyle cellStyle, int rowIndex)
{
var w = GetLabelWidth();
var r = base.GetContentBounds(graphics, cellStyle, rowIndex);
return new Rectangle(r.Left + w, r.Top, r.Width - w, r.Height);
}
protected override void OnContentClick(DataGridViewCellEventArgs e)
{
base.OnContentClick(e);
var g = this.DataGridView;
var c = (DataGridViewAllocationControlColumn)this.OwningColumn;
var r1 = GetContentBounds(e.RowIndex);
var r2 = g.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
var p = new Point(r2.Left + r1.Left, r2.Top + r1.Bottom);
if (c.ContextMenuStrip != null)
c.ContextMenuStrip.Show(g, p);
}
private int GetLabelWidth()
{
var c = (DataGridViewAllocationControlColumn)this.OwningColumn;
var text = c.LabelText;
return TextRenderer.MeasureText(text, c.DefaultCellStyle.Font).Width;
}
}