I am trying to load a custom column (code below) in datagridview in winforms, the custom column binds a integer value into it and displays the integer value along with a unchecked checkbox in it:
public class LabelledCheckBoxColumn : DataGridViewCheckBoxColumn
{
public LabelledCheckBoxColumn()
{
this.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
}
public override DataGridViewCell CellTemplate
{
get
{
return new LabelledCheckBoxCell();
}
}
}
public class LabelledCheckBoxCell : DataGridViewCheckBoxCell
{
private int labelValue;
private bool cellInitComplete;
public LabelledCheckBoxCell()
{
cellInitComplete = false;
}
public LabelledCheckBoxCell(int value) { labelValue = value; }
public int LabelValue
{
set { labelValue = value; }
get { return labelValue; }
}
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)
{
// the base Paint implementation paints the check box
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
// now let's paint the text
// Get the check box bounds: they are the content bounds
Rectangle contentBounds = this.GetContentBounds(rowIndex);
// Compute the location where we want to paint the string.
Point stringLocation = new Point();
// Compute the Y.
// NOTE: the current logic does not take into account padding.
stringLocation.Y = cellBounds.Y + 4;
// Compute the X.
// Content bounds are computed relative to the cell bounds
// - not relative to the DataGridView control.
stringLocation.X = cellBounds.X + contentBounds.Right + 4;
// Paint the string.
graphics.DrawString(labelValue.ToString(), Control.DefaultFont, System.Drawing.Brushes.Black, stringLocation);
}
protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, System.ComponentModel.TypeConverter valueTypeConverter, System.ComponentModel.TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
{
if (!cellInitComplete)
{
labelValue = int.Parse(value.ToString());
value = false;
cellInitComplete = true;
}
return base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context);
}
}
As you can see from my custom cell, i load the binding value for first time only, so its becomes readonly. When GetFormattedValue is called for second time i takes the value for checkbox.
The problem i am facing right now is, when i load this in datagridview with more than 2 rows, for first two rows the custom column displays the correct value of binding value but from 3rd row onwards it always displays the value of second row and by default selects the checkbox. While debugging i found that for 1st and second row the cellInitComplete bool is false as expected but from third row onwards even on initial load its magically changed to true and labelValue also has the value of second row.
I am not sure what i shud do to prevent this happening, Which method should i override to get the expected behaviour ?
Is this the behavior of Shared Cell concept in datagridview ?.