views:

282

answers:

2

I've created custom column(DataGridViewButtonControlColumn) and cell(ButtonControlCell) classes to hold System.Windows.Forms.Button controls. The buttons get added to the columns and get displayed properly. Before I set the button as the value of a ButtonControlCell, I attach an event handler for "Click". But this handler is not called when a button is clicked.

I add the button to the DataGridView's controls in the overridden Paint function.

Are there any specific steps which I have to follow to register the Button with the DataGridView?

Code:

public class ButtonControlCell : DataGridViewTextBoxCell
    {
.
.
.
protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);

            if (btnVal != null)
            {
                btnVal.Size = new System.Drawing.Size(80, 20);
                btnVal.Location = cellBounds.Location;
                this.DataGridView.Controls.Add(btnVal);
            }            
        }
.
.
.
protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
        {
            // This is not called when the button is clicked (which is correct I guess)
            base.OnMouseClick(e);

            if (btnVal != null)
            {
                btnVal.PerformClick();
            }
        }
.
.
}

In the implementation:

private void AddButtonCell(string sText, EventHandler oEh, DataGridViewButtonColumn oClm, DataGridView dgvParent, int iRow, int iColumn)
        {
            Button btnTemp = new Button();
            btnTemp.Height = 20;
            btnTemp.Width = 60;
            btnTemp.Anchor = AnchorStyles.Top;
            btnTemp.Text = sText;
            btnTemp.Click += new EventHandler(btnTemp_Click);
            btnTemp.Tag = new Point(iRow, iColumn);

            Controls.Add(btnTemp);

            dgvParent.Rows[iRow].Cells[iColumn].Value = btnTemp;
        }

        void btnTemp_Click(object sender, EventArgs e)
        {
            Button btnSender = (Button)sender;

            DataGridViewRow r = dgvResults.Rows[((Point)btnSender.Tag).X];

            TagInfo oRet = new TagInfo((string)r.Cells[iTitleColIndex].Value, (string)r.Cells[iArtistColIndex].Value,
                (string)r.Cells[iAlbumColIndex].Value);
            oRet.imgAlbumArt = (System.Drawing.Image)r.Cells[iArtColIndex].Tag;
            oParent.TagWithInfo(oRet, true);
        }
A: 

If your goal is to just have a button the user can click you can use the built-in DataGridViewButtonColumn (DataGridViewButtonColumn).

Robert Höglund
I was using a DataGridViewButtonColumn but it wasn't behaving the way I wanted to. The control gets resized to fill the cell and I couldn't find a property to prevent this.BTW, I'm temporarily using a DataGridViewLinkColumn, till I could figure out how to fire the click event
Gayan
A: 

The method used to achieve this is to catch an event (e.g. button click) performed on the DataGrid, get the control and perform any additional tasks depending on that. Found the answer by going through several tutorials on custom DataGridView s.

Gayan