I'm trying to create a DataGridView column hosted with Radiobuttons. I've been following this MSDN article.
Although I have changed the code from the tutorial to write my own classes, it doesn't work as expected. The thing is I'm not entirely sure what I'm missing. It gives no errors when compiling. But it appears as Checkboxes instead of Radiobuttons.
I have attached the Visual Studio project here. And for those who are unsure about downloading unknown attachments, here are the 3 classes I have written.
RadiobuttonColumn
class. It inherits the DataGridViewColumn
class.
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
class RadiobuttonColumn : DataGridViewColumn
{
public RadiobuttonColumn()
: base(new RadiobuttonCell())
{
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
if (value != null && !value.GetType().IsAssignableFrom(typeof(RadiobuttonCell)))
{
throw new InvalidCastException("Must be a RadiobuttonCell");
}
}
}
}
}
UPDATED RadiobuttonCell
class inherits DataGridViewCell
class.
using System;
using System.Windows.Forms;
using System.Drawing;
namespace DataGridView_Radiobutton_column
{
public class RadiobuttonCell : DataGridViewCell
{
public RadiobuttonCell()
: base()
{
}
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
RadiobuttonEditingControl rdb = DataGridView.EditingControl as RadiobuttonEditingControl;
if (this.Value == null)
{
rdb.Checked = false;
}
else
{
rdb.Checked = (Boolean)this.Value;
}
}
public override Type EditType
{
get
{
return typeof(RadiobuttonEditingControl);
}
}
public override Type ValueType
{
get
{
return typeof(Boolean);
}
}
public override object DefaultNewRowValue
{
get
{
return false;
}
}
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);
Rectangle rectRadioButton = default(Rectangle);
rectRadioButton.Width = 14;
rectRadioButton.Height = 14;
rectRadioButton.X = cellBounds.X + (cellBounds.Width - rectRadioButton.Width) / 2;
rectRadioButton.Y = cellBounds.Y + (cellBounds.Height - rectRadioButton.Height) / 2;
ControlPaint.DrawRadioButton(graphics, rectRadioButton, ButtonState.Normal);
}
}
}
The RadiobuttonEditingControl
class inherits the RadioButton
class and implements IDataGridViewEditingControl
Interface's methods.
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
class RadiobuttonEditingControl : RadioButton, IDataGridViewEditingControl
{
DataGridView dataGridView;
private bool valueChanged = false;
int rowIndex;
public RadiobuttonEditingControl()
{
this.Checked = false;
}
public object EditingControlFormattedValue
{
get
{
return this.Checked = true;
}
set
{
this.Checked = false;
}
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
}
public int EditingControlRowIndex
{
get
{
return rowIndex;
}
set
{
rowIndex = value;
}
}
public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
{
switch (key & Keys.KeyCode)
{
case Keys.Space:
return true;
default:
return !dataGridViewWantsInputKey;
}
}
public void PrepareEditingControlForEdit(bool selectAll)
{
}
public bool RepositionEditingControlOnValueChange
{
get
{
return false;
}
}
public DataGridView EditingControlDataGridView
{
get
{
return dataGridView;
}
set
{
dataGridView = value;
}
}
public bool EditingControlValueChanged
{
get
{
return valueChanged;
}
set
{
valueChanged = value;
}
}
public Cursor EditingPanelCursor
{
get
{
return base.Cursor;
}
}
protected override void OnCheckedChanged(EventArgs eventArgs)
{
valueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.Checked = false;
}
}
}
If anyone could take a look at this and point me to the right direction as to what changes should be done in the code, I'd be grateful.
Thank you.
What happens when you begin editing a cell? It turns into a radio button.
This is because you derived from a checkbox cell which paints itself as a checkbox.
The DGV is not a grid of controls. It's a grid of boxes that are painted to look like controls until the user attempts to edit a cell. At that point the DGV moves the cell's (one and only) editing control into position and makes it visible for the user to interact with.
You're going to have to derive from the base DataGridViewCell class and implement all of the painting code too.
The example code doesn't have to do this because a textbox cell knows how to paint text.
Updated
The ControlPaint class can help you out.