I want to add a custom DataGridViewColumn
to my DataGridView
. This column should create the following cell per row
At first I created
I took this code and modified it to something a bit more dynamic this was a great start for me to build off of and I really appreciate this. I wanted to be able to select a folder with the button and open the folder by clicking the link.
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Windows.Forms.VisualStyles;
using System.IO;
namespace Project
{
public class LinkButtonColumn : DataGridViewButtonColumn
{
private EventHandler buttonClickHandler;
private EventHandler linkClickHandler;
public LinkButtonColumn()
{
this.CellTemplate = new DataGridViewLinkButtonCell();
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
base.CellTemplate = value;
DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
if (cell != null)
cell.ButtonClickHandler = ButtonClickHandler;
cell.LinkClickHandler = LinkClickHandler;
}
}
public EventHandler LinkClickHandler
{
get
{
return linkClickHandler;
}
set
{
DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
if (cell != null)
{
if (value != null)
cell.LinkClickHandler += value;
else if (linkClickHandler != null)
cell.LinkClickHandler -= linkClickHandler;
}
linkClickHandler = value;
}
}
public EventHandler ButtonClickHandler
{
get
{
return buttonClickHandler;
}
set
{
DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
if (cell != null)
{
if (value != null)
cell.ButtonClickHandler += value;
else if (buttonClickHandler != null)
cell.ButtonClickHandler -= buttonClickHandler;
}
buttonClickHandler = value;
}
}
}
internal sealed class DataGridViewLinkButtonColumn : DataGridViewColumn
{
private EventHandler buttonClickHandler;
private EventHandler linkClickHandler;
public string LabelText { get; set; }
public string ButtonText { get; set; }
public override object Clone()
{
var c = (DataGridViewLinkButtonColumn)base.Clone();
c.LabelText = this.LabelText;
c.ButtonText = this.ButtonText;
return c;
}
public DataGridViewLinkButtonColumn() : base(new DataGridViewLinkButtonCell())
{
}
public EventHandler LinkClickHandler
{
get
{
return linkClickHandler;
}
set
{
DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
if (cell != null)
{
if (value != null)
cell.LinkClickHandler += value;
else if (linkClickHandler != null)
cell.LinkClickHandler -= linkClickHandler;
}
linkClickHandler = value;
}
}
public EventHandler ButtonClickHandler
{
get
{
return buttonClickHandler;
}
set
{
DataGridViewLinkButtonCell cell = CellTemplate as DataGridViewLinkButtonCell;
if (cell != null)
{
if (value != null)
cell.ButtonClickHandler += value;
else if (buttonClickHandler != null)
cell.ButtonClickHandler -= buttonClickHandler;
}
buttonClickHandler = value;
}
}
}
public class DataGridViewLinkButtonCell : DataGridViewButtonCell
{
private Rectangle clickRectangleValue = new Rectangle();
private string buttonPosion = "Middle";
public EventHandler ButtonClickHandler { get; set; }
public EventHandler LinkClickHandler { get; set; }
public Rectangle ClickRectangle
{
get
{
Rectangle newRect = new Rectangle();
switch (buttonPosion)
{
case "Bottom":
newRect = new Rectangle(clickRectangleValue.X + clickRectangleValue.Width - 20, clickRectangleValue.Y + (clickRectangleValue.Height - 20), 20, 20);
break;
case "Middle":
newRect = new Rectangle(clickRectangleValue.X + clickRectangleValue.Width - 20, clickRectangleValue.Y + ((clickRectangleValue.Height - 20) / 2), 20, 20);
break;
case "Top":
newRect = new Rectangle(clickRectangleValue.X + clickRectangleValue.Width - 20, clickRectangleValue.Y, 20, 20);
break;
}
return newRect;
}
}
public override object Clone()
{
DataGridViewLinkButtonCell cell = base.Clone() as DataGridViewLinkButtonCell;
if (cell != null)
{
cell.ButtonClickHandler = ButtonClickHandler;
cell.LinkClickHandler = LinkClickHandler;
}
return cell;
}
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 = (DataGridViewLinkButtonColumn)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);
Color forecolor = Color.Black;
TextFormatFlags horizontal = TextFormatFlags.HorizontalCenter;
TextFormatFlags vertical = TextFormatFlags.VerticalCenter;
switch (cellStyle.Alignment)
{
case DataGridViewContentAlignment.BottomCenter:
horizontal = TextFormatFlags.HorizontalCenter;
vertical = TextFormatFlags.Bottom;
break;
case DataGridViewContentAlignment.BottomLeft:
horizontal = TextFormatFlags.Left;
vertical = TextFormatFlags.Bottom;
break;
case DataGridViewContentAlignment.BottomRight:
horizontal = TextFormatFlags.Right;
vertical = TextFormatFlags.Bottom;
break;
case DataGridViewContentAlignment.MiddleCenter:
horizontal = TextFormatFlags.HorizontalCenter;
vertical = TextFormatFlags.VerticalCenter;
break;
case DataGridViewContentAlignment.MiddleLeft:
horizontal = TextFormatFlags.Left;
vertical = TextFormatFlags.VerticalCenter;
break;
case DataGridViewContentAlignment.MiddleRight:
horizontal = TextFormatFlags.Right;
vertical = TextFormatFlags.VerticalCenter;
break;
case DataGridViewContentAlignment.TopCenter:
horizontal = TextFormatFlags.HorizontalCenter;
vertical = TextFormatFlags.Top;
break;
case DataGridViewContentAlignment.TopLeft:
horizontal = TextFormatFlags.Left;
vertical = TextFormatFlags.Top;
break;
case DataGridViewContentAlignment.TopRight:
horizontal = TextFormatFlags.Right;
vertical = TextFormatFlags.Top;
break;
}
if (g.Rows[rowIndex].Cells[c.Index].Selected)
{
if (value != null)
{
if (Directory.Exists(value.ToString()) || File.Exists(value.ToString()))
{
forecolor = Color.Red;
TextRenderer.DrawText(graphics, value.ToString(), new Font(cellStyle.Font, FontStyle.Underline),
r1, forecolor, Color.Empty,
horizontal |
vertical |
TextFormatFlags.TextBoxControl |
TextFormatFlags.WordBreak |
TextFormatFlags.EndEllipsis);
}
else
{
forecolor = Color.Blue;
TextRenderer.DrawText(graphics, value.ToString(), new Font(cellStyle.Font, FontStyle.Regular),
r1, Color.White, Color.Empty,
horizontal |
vertical |
TextFormatFlags.TextBoxControl |
TextFormatFlags.WordBreak |
TextFormatFlags.EndEllipsis);
}
}
}
else
{
if (value != null)
{
if (Directory.Exists(value.ToString()) || File.Exists(value.ToString()))
{
forecolor = Color.Blue;
TextRenderer.DrawText(graphics, value.ToString(), new Font(cellStyle.Font, FontStyle.Underline),
r1, forecolor, Color.Empty,
horizontal |
vertical |
TextFormatFlags.TextBoxControl |
TextFormatFlags.WordBreak |
TextFormatFlags.EndEllipsis);
}
else
{
forecolor = Color.Blue;
TextRenderer.DrawText(graphics, value.ToString(), new Font(cellStyle.Font, FontStyle.Regular),
r1, Color.Black, Color.Empty,
horizontal |
vertical |
TextFormatFlags.TextBoxControl |
TextFormatFlags.WordBreak |
TextFormatFlags.EndEllipsis);
}
}
}
Point cursorPosition = this.DataGridView.PointToClient(Cursor.Position);
if (cellBounds.Contains(cursorPosition))
{
clickRectangleValue = cellBounds;
Rectangle newRect = new Rectangle(cellBounds.X + 1,
cellBounds.Y + 1, cellBounds.Width - 4,
cellBounds.Height - 4);
DataGridViewCellStyle style = cellStyle;
style.Alignment = DataGridViewContentAlignment.MiddleCenter;
base.Paint(graphics, clipBounds, ClickRectangle, rowIndex, elementState,
value, c.ButtonText, errorText, style, advancedBorderStyle,
DataGridViewPaintParts.All);
}
}
protected override Rectangle GetContentBounds(Graphics graphics,
DataGridViewCellStyle cellStyle, int rowIndex)
{
var r = base.GetContentBounds(graphics, cellStyle, rowIndex);
switch (cellStyle.Alignment)
{
case DataGridViewContentAlignment.BottomCenter:
buttonPosion = "Bottom";
break;
case DataGridViewContentAlignment.BottomLeft:
buttonPosion = "Bottom";
break;
case DataGridViewContentAlignment.BottomRight:
buttonPosion = "Bottom";
break;
case DataGridViewContentAlignment.MiddleCenter:
buttonPosion = "Middle";
break;
case DataGridViewContentAlignment.MiddleLeft:
buttonPosion = "Middle";
break;
case DataGridViewContentAlignment.MiddleRight:
buttonPosion = "Middle";
break;
case DataGridViewContentAlignment.TopCenter:
buttonPosion = "Top";
break;
case DataGridViewContentAlignment.TopLeft:
buttonPosion = "Top";
break;
case DataGridViewContentAlignment.TopRight:
buttonPosion = "Top";
break;
}
clickRectangleValue = r;
return new Rectangle(ClickRectangle.X, ClickRectangle.Y, ClickRectangle.Width, ClickRectangle.Height);
}
protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
{
int x = e.X;
int y = e.Y;
Point cursorPosition = this.DataGridView.PointToClient(Cursor.Position);
var g = this.DataGridView;
var r1 = GetContentBounds(e.RowIndex);
var r2 = g.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
r1.X = r1.X + r2.X;
r1.Y = r1.Y + r2.Y;
if (r1.Contains(cursorPosition))
{
if (ButtonClickHandler != null)
{
this.ButtonClickHandler.Invoke(this,e);
}
}
else
{
if (r2.Contains(cursorPosition))
{
if (LinkClickHandler != null)
{
this.LinkClickHandler.Invoke(this, e);
}
}
}
}
protected override void OnMouseEnter(int rowIndex)
{
Cursor.Current = Cursors.Hand;
this.DataGridView.Cursor = Cursor.Current;
this.DataGridView.InvalidateCell(this);
}
protected override void OnMouseLeave(int rowIndex)
{
this.DataGridView.InvalidateCell(this);
Cursor.Current = Cursors.Default;
this.DataGridView.Cursor = Cursor.Current;
}
}
}
Then I pragmatically add the column to the grid.
if (!Addendum_dataGridView.Columns.Contains("Folder_Location"))
{
DataGridViewLinkButtonColumn textButtonColumn = new DataGridViewLinkButtonColumn();
textButtonColumn.ValueType = typeof(string);
textButtonColumn.HeaderText = "Folder Location";
textButtonColumn.ButtonText = "...";
textButtonColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
textButtonColumn.DefaultCellStyle.Padding = new Padding(1, 0, 0, 0);
textButtonColumn.Width = 100;
textButtonColumn.Name = "Folder_Location";
textButtonColumn.DataPropertyName = "Folder_Location";
textButtonColumn.LinkClickHandler = (o, e) =>
{
if(Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value != DBNull.Value)
{
if (Directory.Exists(Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value.ToString()) || File.Exists(Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value.ToString()))
{
Process.Start(Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value.ToString());
}
}
};
textButtonColumn.ButtonClickHandler = (o, e) =>
{
CommonOpenFileDialog cofd = new CommonOpenFileDialog();
cofd.IsFolderPicker = true;
cofd.Multiselect = false;
cofd.Title = "Select Addendum Folder";
if (Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value != DBNull.Value)
{
cofd.InitialDirectory = Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Value.ToString();
}
else
{
cofd.InitialDirectory = Directory.GetParent(Directory.GetParent(SQL_Commands.Get_Data("select top 1 Quote_Location from [Index].[Estimates_Project_info] where Project_ID = " + P_ID).FirstOrDefault()).ToString()).ToString();
}
if (cofd.ShowDialog() == CommonFileDialogResult.Ok)
{
if (Addendum_dataGridView.Rows[e.RowIndex].IsNewRow)
{
int r = Addendum_dataGridView.NewRowIndex;
DataTable dt = Addendum_dataGridView.DataSource as DataTable;
DataRow row = dt.NewRow();
row["Addendum_Number"] = Path.GetFileNameWithoutExtension(cofd.FileName.ToString());
row["Folder_Location"] = cofd.FileName.ToString();
dt.Rows.Add(row);
dt = Addendum_dataGridView.DataSource as DataTable;
bool blank = true;
DataGridViewRow dgvr = Addendum_dataGridView.Rows[Addendum_dataGridView.Rows.Count - 2];
for (int i = 0; i < Addendum_dataGridView.ColumnCount;i++)
{
if (dgvr.Cells[i].Value != DBNull.Value)
{
blank = false;
}
}
if (blank)
{
Addendum_dataGridView.Rows.RemoveAt(Addendum_dataGridView.Rows.Count - 2);
}
insert_Addendum = true;
Addendum_Data_Update(r);
}
else
{
Addendum_dataGridView["Folder_Location",e.RowIndex].Value = cofd.FileName.ToString();Addendum_dataGridView.Rows[e.RowIndex].Cells[Addendum_dataGridView.Columns["Folder_Location"].Index].Selected = true;
Addendum_Data_Update(e.RowIndex);
}
}
};
Addendum_dataGridView.Columns.Insert(Addendum_dataGridView.Columns.Count,textButtonColumn);
}