Microsoft Developer Network > Forums Home > Windows Forms Forums > Windows Forms Data Controls and Databinding > Need a DataGridView Custom Column of Type ListView or CheckedListBox
Ask a questionAsk a question
 

AnswerNeed a DataGridView Custom Column of Type ListView or CheckedListBox

  • Tuesday, March 24, 2009 12:09 PMJamesDavidAnderson Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I am attempting to write a new DataGridView custom column type based on the samples I have found so far but cannot get a ListView or CheckListBox to work correctly. One issue is that the list needs to be bound to a data source that is different from the containing DataGridView. I have not been able to locate any code samples that do this. Can someone kindly point me in the right direction?

    The Microsoft code sample showing a calendar custom column is good as far as it goes but does not support data binding in the manner I have described above.

Answers

  • Friday, March 27, 2009 9:14 AMLinda LiuMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code

    Hi James,

    In order to display ListView or CheckListBox in a DataGridView cell, you need to paint the cell by yourself. The following is a sample on how to embed CheckListBox in DataGridView cell. In this sample, I bind the DataGridView to a data source and bind the the custom DataGridViewColumn to a property of type List<string> in the data source.

    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.ComponentModel.TypeConverter valueTypeConverter, System.ComponentModel.TypeConverter 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.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);  
                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;  
                }  
            }          
        }    


    This is a just a start point. You may need to modify it to meet your actual requirement.

    If you have any question, please feel free to let me know.

All Replies

  • Friday, March 27, 2009 9:14 AMLinda LiuMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code

    Hi James,

    In order to display ListView or CheckListBox in a DataGridView cell, you need to paint the cell by yourself. The following is a sample on how to embed CheckListBox in DataGridView cell. In this sample, I bind the DataGridView to a data source and bind the the custom DataGridViewColumn to a property of type List<string> in the data source.

    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.ComponentModel.TypeConverter valueTypeConverter, System.ComponentModel.TypeConverter 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.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);  
                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;  
                }  
            }          
        }    


    This is a just a start point. You may need to modify it to meet your actual requirement.

    If you have any question, please feel free to let me know.

  • Friday, April 17, 2009 7:36 PMJon Ohmann Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I am also trying to implement this...I have gotten the code you posted to work...sort of.  I converted it to VB.NET...and I can get the checked listbox to display...but I want to be able to retrieve the selected items and cannot seem to figure that out.  Any help would be appreciated.  I am not binding the list...simply adding the list by hand.



  • Sunday, May 30, 2010 8:19 PMJanWrage Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hey Jon, have you solved your problem with retrieving the items from the listbox.

    Please share your converted VB.Net-Code.

    Thanks and regards

    Jan