I have another way to do this, we can take the following steps:
1). Make a usercontrol to host a textbox and a button, as shown in my following sample, the TextAndButtonControl class which inherited from usercontrol.
2). Create a TextAndButtonControl instance(NOTICE: we just need one), add it into the control collection of the DataGridView, initially make it invisible.
3). Handle the DataGridView.CellPainting event to draw a textbox and button style on the cell, which make the cell looked like some kind hosting a usercontrol in it.
4). Handle the DataGridView.CellBeginEdit event to show the usercontrol right in the cell while editing, you can edit in the textbox in the usercontrol and click the button, write your logic in the Click event of the button, I just show a message box for example in this sample.
5). Handle the DataGridView.CellEndEdit event to update the cell value.
6). Handle the DataGridView.Scroll event to reset the location and size of the usercontrol while scrolling. Without handling this, the usercontrol would stay still while scrolling.
That's all. I write a sample for your information. Enjoy taking it. Any question about this please no hesitate to let me know. Best Regards. Zhixin Ye
Code Snippet
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Text;
System.Windows.Forms;
Sample5
public partial class DgvTextAndButton : Form
public DgvTextAndButton()
private void DgvTextAndButton_Load(object sender, EventArgs e)
DataTable dt = new DataTable();
"col1");
"col2");
for (int j = 0; j < 20; j++)
"col1"+j.ToString(),"col2"+j.ToString());
this.dataGridView1.DataSource = dt;
this.dataGridView1.Columns[0].Width = 150;
this.txbtnControl = new TextAndButtonControl();
this.txbtnControl.Visible = false;
this.dataGridView1.Controls.Add(this.txbtnControl);
//Handle this event to paint a textbox and button style in the cell,
//this painting avoid using amount of usercontrols, we just need one
this.dataGridView1.CellPainting += new DataGridViewCellPaintingEventHandler(dataGridView1_CellPainting);
//Handle the cellbeginEdit event to show the usercontrol in the cell while editing
this.dataGridView1.CellBeginEdit += new DataGridViewCellCancelEventHandler(dataGridView1_CellBeginEdit);
//Handle the cellEndEdit event to update the cell value
this.dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);
//Handle the scroll event to reset the location and size of the usercontrol while scrolling
this.dataGridView1.Scroll += new ScrollEventHandler(dataGridView1_Scroll);
TextAndButtonControl txbtnControl;
void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
if (e.ColumnIndex == 0 && e.RowIndex > -1 && e.RowIndex != this.dataGridView1.NewRowIndex)
Rectangle textRect = e.CellBounds;
Rectangle btnRect = e.CellBounds;
DataGridViewPaintParts.All);
ControlPaint.DrawButton(e.Graphics, btnRect, ButtonState.Normal);
StringFormat formater = new StringFormat();
StringAlignment.Center;
"click", e.CellStyle.Font, new SolidBrush(e.CellStyle.ForeColor), btnRect, formater);
true;
void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
if (e.ColumnIndex == 0 && e.RowIndex > -1 && e.RowIndex != this.dataGridView1.NewRowIndex)
Rectangle rect = this.dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
this.txbtnControl.Location = rect.Location;
this.txbtnControl.Size = rect.Size;
this.txbtnControl.Text = this.dataGridView1.CurrentCell.Value.ToString();
this.txbtnControl.ButtonText = "click";
this.txbtnControl.renderControl();
this.txbtnControl.Visible = true;
void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
if (e.ColumnIndex == 0 && e.RowIndex > -1 && e.RowIndex != this.dataGridView1.NewRowIndex)
this.dataGridView1.CurrentCell.Value = this.txbtnControl.Text;
this.txbtnControl.Visible = false;
void dataGridView1_Scroll(object sender, ScrollEventArgs e)
if (this.txbtnControl.Visible == true)
Rectangle r = this.dataGridView1.GetCellDisplayRectangle(
this.dataGridView1.CurrentCell.ColumnIndex,
this.dataGridView1.CurrentCell.RowIndex,
true);
this.txbtnControl.Location = r.Location;
this.txbtnControl.Size = r.Size;
class TextAndButtonControl : UserControl
private TextBox textbox1;
private Button button1;
public TextAndButtonControl()
this.textbox1 = new TextBox();
this.Controls.Add(this.textbox1);
this.button1 = new Button();
this.Controls.Add(this.button1);
this.renderControl();
this.button1.Click += new EventHandler(button1_Click);
void button1_Click(object sender, EventArgs e)
MessageBox.Show("Click! The value is:" + this.Text);
public string Text
get { return this.textbox1.Text; }
set { this.textbox1.Text = value; }
public string ButtonText
get { return this.button1.Text; }
set { this.button1.Text = value; }
public void renderControl()
this.textbox1.Location = new Point(0, 0);
this.textbox1.Width = 2 * this.Width / 3;
this.textbox1.Height = this.Height;
this.button1.Location = new Point(2 * this.Width / 3, 0);
this.button1.Width = this.Width / 3;
this.button1.Height = this.Height;
nathan:
waht function would you like to fullfill ?
if you can take tow columns,
you can use DatagridviewTextboxColumn and DataGridviewButtonColumn in same row,
and if you want it looks like one column, you can redraw the column head But I think it more code if you custom your own datagridview cell you want.
|