add custom DataGridViewColumn with label and button per cell

戏子无情 提交于 2019-12-02 05:37:17

There are 3 main pillars for a new column type:

  • DataGridViewColumn is responsible for properties which you set in design mode in column editor of the control.
  • DataGridViewCell is responsible for appearance of the cell. It renders the value and other painting parts in cell and initialize the editing control (if the column has any editing control).
  • DataGridViewEditingControl is responsible for editing the value of the cell.

When creating a new column you can derive from DataGridViewColumn or one of its derived classes. Also when creating a new cell for the column, you can derive from DataGridViewCell or one of its derived classes. Also when creating a new editing control, you can derive from one of the existing editing controls, or you can start by deriving from a control class and implementing IDataGridViewEditingControl interface.

Keep in mind, the editing control will be shown just in the editing cell. Rest of cells show what you render in the paint method of the cell.

Example

Here in this post, I've shared an example of drawing a custom cell containing a label and a button. I've not created an editing control because for this example, we can derive from DataGridViewButtonColumn and DataGridViewButtonCell without needing to create an editing control. We just add some properties to column and change paint logic and override OnContentClick to show the context menu, like this:

The custom column has LabelText and ButtonText properties. When you click on the button part, it shows the ContextMenuStrip which you assigned to corresponding property.

Note: This is just an example and depending on the requirements, you may want to change properties, rendering logic and the way that you show menu or anything else. But I think it's a good start point.

Here is the code:

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;
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!