Custom CheckedListBox DataGridView Column
Hello,
Here's a working custom control class on how to embed CheckedListBox as a datagridview column. Source: Need a DataGridView Custom Column of Type ListView or CheckedListBox However, this class lacked functionalities such as obtaining the checked items and preserving the checked items during painting of the datagridview cell.
Here's the custom class:
For the first requirement, I added a property to retrieve the checked items. Here's the property below:
Here's how to get the checked items.
For the second requirement, it's a bit tricky. I have overriden the detaching control event in the datagridview cell and added a flag value for preserving the checked items during repainting of the objects.
See sample solution in codeproject: how to add checkedlistbox in datagridview column
Output
Cheers!
Here's a working custom control class on how to embed CheckedListBox as a datagridview column. Source: Need a DataGridView Custom Column of Type ListView or CheckedListBox However, this class lacked functionalities such as obtaining the checked items and preserving the checked items during painting of the datagridview cell.
Here's the custom class:
public class CheckedListBoxColumn : DataGridViewColumn { public CheckedListBoxColumn() : base(new CheckedListBoxCell()) { } public override DataGridViewCell CellTemplate { get { return base.CellTemplate; } set { if (value != null && !value.GetType().IsAssignableFrom(typeof(CheckedListBoxCell))) { throw new InvalidCastException("Must be a CheckedListBoxCell"); } base.CellTemplate = value; } } } public class CheckedListBoxCell : DataGridViewCell { public CheckedListBoxCell() : base() { } public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) { // Set the value of the editing control to the current cell value. base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); CheckedListBoxEditingControl ctl = DataGridView.EditingControl as CheckedListBoxEditingControl; InitializeCheckedListBox(ctl,(ICollection)this.FormattedValue); } private void InitializeCheckedListBox(CheckedListBox ctrl,ICollection value) { ctrl.Items.Clear(); foreach(object obj in value) { ctrl.Items.Add(obj.ToString()); } ctrl.Tag = this.Value; } public override Type EditType { get { return typeof(CheckedListBoxEditingControl); } } protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, System.ComponentModelTypeConverter valueTypeConverter, System.ComponentModelTypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) { if (value == null) { return new List<object>(); } return base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context); } public override Type FormattedValueType { get { return typeof(ICollection); } } public override Type ValueType { get { return typeof(ICollection); } } private CheckedListBox internalControl; protected override void Paint(System.DrawingGraphics graphics, System.DrawingRectangle clipBounds, System.DrawingRectangle 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); graphics.FillRectangle(new SolidBrush(cellStyle.BackColor), cellBounds); if (internalControl == null) { internalControl = new CheckedListBox(); } internalControl.Items.Clear(); ICollection collection = value as ICollection; if (collection != null) { foreach (object obj in collection) { internalControl.Items.Add(obj); } Bitmap bmp = new Bitmap(cellBounds.Width, cellBounds.Height); internalControl.DrawToBitmap(bmp,new Rectangle(0,0,bmp.Width,bmp.Height)); graphics.DrawImage(bmp,cellBounds,new Rectangle(0,0,bmp.Width,bmp.Height),GraphicsUnit.Pixel); } } protected override void OnClick(DataGridViewCellEventArgs e) { this.DataGridView.BeginEdit(false); base.OnClick(e); } } class CheckedListBoxEditingControl : CheckedListBox, IDataGridViewEditingControl { DataGridView dataGridView; private bool valueChanged = false; int rowIndex; public CheckedListBoxEditingControl() { } // Implements the IDataGridViewEditingControl.EditingControlFormattedValue // property. public object EditingControlFormattedValue { get { return this.Tag; } set { // this.Tag = value; } } // Implements the // IDataGridViewEditingControl.GetEditingControlFormattedValue method. public object GetEditingControlFormattedValue( DataGridViewDataErrorContexts context) { return EditingControlFormattedValue; } // Implements the // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method. public void ApplyCellStyleToEditingControl( DataGridViewCellStyle dataGridViewCellStyle) { this.Font = dataGridViewCellStyle.Font; this.ForeColor = dataGridViewCellStyle.ForeColor; this.BackColor = dataGridViewCellStyle.BackColor; } // Implements the IDataGridViewEditingControl.EditingControlRowIndex // property. public int EditingControlRowIndex { get { return rowIndex; } set { rowIndex = value; } } // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey // method. public bool EditingControlWantsInputKey( Keys key, bool dataGridViewWantsInputKey) { // Let the DateTimePicker handle the keys listed. switch (key & Keys.KeyCode) { case Keys.Left: case Keys.Up: case Keys.Down: case Keys.Right: case Keys.Home: case Keys.End: case Keys.PageDown: case Keys.PageUp: return true; default: return !dataGridViewWantsInputKey; } } // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit // method. public void PrepareEditingControlForEdit(bool selectAll) { // No preparation needs to be done. } // Implements the IDataGridViewEditingControl // .RepositionEditingControlOnValueChange property. public bool RepositionEditingControlOnValueChange { get { return false; } } // Implements the IDataGridViewEditingControl // .EditingControlDataGridView property. public DataGridView EditingControlDataGridView { get { return dataGridView; } set { dataGridView = value; } } // Implements the IDataGridViewEditingControl // .EditingControlValueChanged property. public bool EditingControlValueChanged { get { return valueChanged; } set { valuevalueChanged = value; } } // Implements the IDataGridViewEditingControl // .EditingPanelCursor property. public Cursor EditingPanelCursor { get { return base.Cursor; } } }
public ICollection CheckedItems { get { if (internalControl == null) return null; else { if (internalControl != null) { if (internalControl.CheckedItems.Count > 0) { return internalControl.CheckedItems; } else { if ((CheckedListBox)this.DataGridView.Rows[RowIndex].Cells[ColumnIndex].DataGridView.EditingControl != null) { CheckedListBox checks = (CheckedListBox)this.DataGridView.Rows[RowIndex].Cells[ColumnIndex].DataGridView.EditingControl; if (checks.CheckedItems.Count > 0) return checks.CheckedItems; else return null; } else return null; } } else { return null; } } } }
private void btnShow_Click(object sender, EventArgs e) { StringBuilder builder = new StringBuilder(); foreach (DataGridViewRow item in dgCheckListColumn1.Rows) { DataGridViewCell cell = item.Cells[1]; if (((cell as CheckedListBoxCell).CheckedItems != null)) { if (((cell as CheckedListBoxCell).CheckedItems.Count > 0)) { foreach (var checkItem in ((cell as CheckedListBoxCell).CheckedItems)) { builder.AppendLine(String.Format("Row {0} : item: {1}", item.Index + 1, checkItem.ToString())); } builder.AppendLine(Environment.NewLine); } } } MessageBox.Show("Checked Items: \n" + builder.ToString()); }
See sample solution in codeproject: how to add checkedlistbox in datagridview column
Output
Cheers!
How to Set the Collection of Items to the CheckedListBox in DataGridView?
ReplyDeleteHi, I haven't touched the code in years since 2014 since this has been sidetracked. I'll look for the project in our repository and will give feedback.
DeleteAs far as I remember, you need to create a dummy model class that holds list of countries and Address.
ReplyDeletepublic class CountryAddressModel
{
public List Countries { get; set; }
public string Address { get; set; }
}
In form load, create a list object with CountryAddressModel as type.
List infoList = new List();
* Populate the list with records
* Then set the datagridview's datasource with the list
dgCheckListColumn1.DataSource = infoList;
Hope this helps.
Hi,
ReplyDeleteThank you very much for the code with information.
Need one help, i have my condition and based on that how can I check the checkbox from code?
Hi, its been a while since I've worked with this example. I advise you to please read the original source of this article. thanks
Delete