Click here to Skip to main content
15,885,278 members
Articles / Programming Languages / C#

DataGridViewColourPicker

Rate me:
Please Sign up or sign in to vote.
4.80/5 (13 votes)
17 May 2009CPOL2 min read 48.8K   1.5K   47   5
A customized column for datagridview to pick a color from a drop down within datagridview
ColorSelectorDGVC_Tester

Introduction

This is one of a series of datagridviewcolumn articles that I developed over the years. Now I want to share them all on CodeProject. Hope you like it.

Background

Datagridview lets you to have a customized editor on datagridview that lets you control the way data in table should be edited and also the way you want to format and show it to your end user client. For example, you have enumerable and want to specify numbers to a sort of action running=1 , jumping=2, having_fun=3 and you store those numbers instead of action names in the database so your end user does not want to interpret the numbers to those action. He wants to see the real action names.

Using the Code

There are three major classes that you should inherit from:

  1. DataGridViewColumn: That is the type of column you chose in Visual Studio. You just specify the cell type you want all cells of this column to be in constructor.
  2. DataGridViewCell or DataGridViewTextBoxCell: In this class, you need to override:
    • Paint: For customized painting of all cells with the same type because it's dependant on the editor. If any error happened in showing datagridview this function is the first place to check.
    • InitializeEditingControl: This function calls every time you click twice on a cell or press F2 on it and datagridview wants to show an editor for cell value. So in this function you create an instance of editor and select current value for editor to change and show it. Remember the value in datagridview is sent as stringvalue so if it is a number, it shows the current value of cell in initialFormattedValue like "43" and you should parse that string value to your type.
  3. IDataGridViewEditingControl Interface adds all functionalities for adapting your editor to datagridview cell edit:
C#
//
using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Text;
using System.Windows.Forms;

namespace FarsiLibrary.Win.Controls
{
    public class DataGridViewColourPickerCell : DataGridViewTextBoxCell
    {
        private DateTime selectedDateTime;
        private static Type valueType = typeof(byte);
        private static Type editType = typeof(DataGridViewColourPickerEditor);
        private StringAlignment verticalAlignment;
        private StringAlignment horizontalAlignment;
        //private FormatInfoTypes format;

        public override Type EditType
        {
            get { return editType; }
        }

        public override Type ValueType
        {
            get { return valueType; }
        }

        public DateTime SelectedDateTime
        {
            get { return selectedDateTime; }
            set { selectedDateTime = value; }
        }

        /// <summary>
        /// Returns the current DataGridView EditingControl 
        /// as a DataGridViewNumericUpDownEditingControl control
        /// </summary>
        private DataGridViewColourPickerEditor EditingFADatePicker
        {
            get { return DataGridView.EditingControl as DataGridViewColourPickerEditor; }
        }

        private const int RECTCOLOR_LEFT = 0;
        private const int RECTCOLOR_TOP = 0;
        private const int RECTCOLOR_WIDTH = 20;
        private const int RECTTEXT_MARGIN = 0;
        private const int RECTTEXT_LEFT = 
		RECTCOLOR_LEFT + RECTCOLOR_WIDTH + RECTTEXT_MARGIN;
        private static StringFormat sf;
        protected override void Paint(Graphics graphics, Rectangle clipBounds, 
	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, 
		DataGridViewPaintParts.All);
            if (DataGridView == null)
                return;

            if (sf == null)
            {
                sf = new StringFormat();
                sf.LineAlignment = StringAlignment.Center;
                sf.Alignment = StringAlignment.Center;
            }

            Color BlockColor = Color.White;

            if (value == null || value.GetType() == typeof(DBNull)) return;
            BlockColor = Color.FromKnownColor((KnownColor)((byte)value));

            Rectangle rec = new Rectangle(cellBounds.X + 3, 
		cellBounds.Y + 3, cellBounds.Width - 8, cellBounds.Height - 8);

            graphics.FillRectangle(new SolidBrush(BlockColor), rec);
            graphics.DrawRectangle(Pens.Black, rec);
            graphics.DrawString(BlockColor.Name, this.DataGridView.Font, 
						Brushes.Black, rec, sf);

            // if (PartPainted(paintParts, DataGridViewPaintParts.ErrorIcon))
        }
        private static bool PartPainted(DataGridViewPaintParts paintParts, 
					DataGridViewPaintParts paintPart)
        {
            return (paintParts & paintPart) != 0;
        }
        [DefaultValue("Center")]
        public StringAlignment VerticalAlignment
        {
            get { return verticalAlignment; }
            set { verticalAlignment = value; }
        }

        [DefaultValue("Near")]
        public StringAlignment HorizontalAlignment
        {
            get { return horizontalAlignment; }
            set { horizontalAlignment = value; }
        }

        private static bool IsInState(DataGridViewElementStates currentState, 
					DataGridViewElementStates checkState)
        {
            return (currentState & checkState) != 0;
        }

        /// <summary>
        /// Little utility function called by the Paint function to see 
        /// if a particular part needs to be painted. 
        /// 

        /// <summary>
        /// Determines whether this cell, at the given row index, 
        /// shows the grid's editing control or not.
        /// The row index needs to be provided as a parameter 
        /// because this cell may be shared among multiple rows.
        /// </summary>
        private bool OwnsEditor(int rowIndex)
        {
            if (rowIndex == -1 || DataGridView == null)
                return false;

            DataGridViewColourPickerEditor editor = 
		DataGridView.EditingControl as DataGridViewColourPickerEditor;
            return editor != null && rowIndex == editor.EditingControlRowIndex;
        }

        internal void SetValue(int rowIndex, DateTime value)
        {
            //SelectedDateTime = value;
            //if (OwnsEditor(rowIndex))
            //    EditingFADatePicker.SelectedDateTime = value;
        }

        public override void InitializeEditingControl(int rowIndex, 
	object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl
		(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            DataGridViewColourPickerEditor editor = 
		DataGridView.EditingControl as DataGridViewColourPickerEditor;

            if (editor != null)
            {
                editor.RightToLeft = DataGridView.RightToLeft;

                string formattedValue = initialFormattedValue.ToString();

                byte o;

                if (byte.TryParse(initialFormattedValue.ToString(), out o))
                {
                    editor.SelectedIndex = o - 1;
                    //editor.Text = "RED";
                }

                //if (string.IsNullOrEmpty(formattedValue))
                //{
                //    editor.SelectedDateTime = DateTime.Now;
                //    editor.mv.MonthViewControl.SetNoneDay();
                //}
                //else
                //{
                //    editor.SelectedDateTime = DateTime.Parse(formattedValue);
                //    editor.mv.MonthViewControl.clock.Dt = editor.SelectedDateTime;
                //}
            }
        }
    }

    public class DataGridViewColourPickerEditor : 
			ColorPicker, IDataGridViewEditingControl
    {
        public void ApplyCellStyleToEditingControl
			(DataGridViewCellStyle dataGridViewCellStyle)
        {
            this.SelectedIndexChanged += new EventHandler
		(DataGridViewFADateTimePickerEditor_SelectedIndexChanged);
        }

        void DataGridViewFADateTimePickerEditor_SelectedIndexChanged
						(object sender, EventArgs e)
        {
            EditingControlValueChanged = true;
            EditingControlFormattedValue = (byte)8;
            if (EditingControlValueChanged == true)
                EditingControlDataGridView.NotifyCurrentCellDirty(true);
        }
        DataGridView _editingControlDataGridView;
        public DataGridView EditingControlDataGridView
        {
            get
            {
                return _editingControlDataGridView;
            }
            set
            {
                _editingControlDataGridView = value;
            }
        }
        object _editingControlFormattedValue;
        public object EditingControlFormattedValue
        {
            get
            {
                return _editingControlFormattedValue;
            }
            set
            {
                _editingControlFormattedValue = value;
            }
        }
        int _editingControlRowIndex;
        public int EditingControlRowIndex
        {
            get
            {
                return _editingControlRowIndex;
            }
            set
            {
                _editingControlRowIndex = value;
            }
        }

        bool _editingControlValueChanged;
        public bool EditingControlValueChanged
        {
            get
            {
                return _editingControlValueChanged;
            }
            set
            {
                _editingControlValueChanged = value;
            }
        }

        public bool EditingControlWantsInputKey
			(Keys keyData, bool dataGridViewWantsInputKey)
        {
            return true;
        }

        public Cursor EditingPanelCursor
        {
            get { return Cursors.Default; }
        }

        public object GetEditingControlFormattedValue
			(DataGridViewDataErrorContexts context)
        {
            if (this.SelectedItem == null)
                return 0;
            return ((byte)((Color)
		((MyColour)this.SelectedItem).Colour).ToKnownColor()).ToString();
        }

        public void PrepareEditingControlForEdit(bool selectAll)
        {

        }

        public bool RepositionEditingControlOnValueChange
        {
            get { return true; }
        }
    }

    //[ToolboxBitmap(typeof(DataGridViewFADateTimePickerColumn), 
    // "DataGridViewFADateTimePickerColumn.bmp")]
    public class DataGridViewColourPickerColumn : DataGridViewColumn
    {
        public DataGridViewColourPickerColumn()
            : base(new DataGridViewColourPickerCell())
        {
        }
        //[Browsable(false)]
        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        //public override DataGridViewCell CellTemplate
        //{
        //    get { return base.CellTemplate; }
        //    set
        //    {
        //        DataGridViewFADateTimePickerCell dataGridViewFADateTimePickerCell = 
        // 		value as DataGridViewFADateTimePickerCell;
        //        if (value != null && dataGridViewFADateTimePickerCell == null)
        //            throw new InvalidCastException("Value provided for CellTemplate 
        // 	    must be of type DataGridViewRadioButtonElements.
        // 		DataGridViewRadioButtonCell or derive from it.");

        //        base.CellTemplate = value;
        //    }
        //}

        /// <summary>
        /// Small utility function that returns the template cell as a 
        /// DataGridViewRadioButtonCell.
        /// </summary>
        //private DataGridViewFADateTimePickerCell FADatePickerCellTemplate
        //{
        //    get { return (DataGridViewFADateTimePickerCell)CellTemplate; }
        //}
    }

    public class ColorPicker : ComboBox
    {
        private const int RECTCOLOR_LEFT = 4;
        private const int RECTCOLOR_TOP = 3;
        private const int RECTCOLOR_WIDTH = 40;
        private const int RECTTEXT_MARGIN = 3;
        private const int RECTTEXT_LEFT = RECTCOLOR_LEFT + 
				RECTCOLOR_WIDTH + RECTTEXT_MARGIN;

        public ColorPicker()
        {
            this.DrawMode = DrawMode.OwnerDrawFixed;
            this.DropDownStyle = ComboBoxStyle.DropDownList;

            for (byte i = 1; i < 174; i++)
            {
                MyColour c = new MyColour();
                c.Colour = Color.FromKnownColor((KnownColor)i);
                c.Colourid = i;
                this.Items.Add(c);
            }
            this.DisplayMember = "Name";
            this.ValueMember = "Colourid";
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
            }
            base.Dispose(disposing);
        }

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            if (e.State == DrawItemState.Selected || e.State == DrawItemState.None)
                e.DrawBackground();


            Graphics Grphcs = e.Graphics;
            Color BlockColor = Color.Empty;
            int left = RECTCOLOR_LEFT;

            if (e.Index == -1)
                BlockColor = SelectedIndex < 0 ? 
			BackColor : Color.FromName(SelectedText);
            else
                BlockColor = ((MyColour)base.Items[e.Index]).Colour;

            Grphcs.FillRectangle(new SolidBrush(BlockColor), 
		left, e.Bounds.Top + RECTCOLOR_TOP, RECTCOLOR_WIDTH, 
		ItemHeight - 2 * RECTCOLOR_TOP);
            Grphcs.DrawRectangle(Pens.Black, left, e.Bounds.Top + 
		RECTCOLOR_TOP, RECTCOLOR_WIDTH, ItemHeight - 2 * RECTCOLOR_TOP);
            Grphcs.DrawString(BlockColor.Name, e.Font, new SolidBrush(ForeColor), 
		new Rectangle(RECTTEXT_LEFT, e.Bounds.Top, 
		e.Bounds.Width - RECTTEXT_LEFT, ItemHeight));
            base.OnDrawItem(e);
        }

        protected override void OnDropDownStyleChanged(EventArgs e)
        {
            if (this.DropDownStyle != ComboBoxStyle.DropDownList) 
			this.DropDownStyle = ComboBoxStyle.DropDownList;
        }
    }

    public class MyColour
    {
        byte _colourid;

        public byte Colourid
        {
            get { return _colourid; }
            set { _colourid = value; }
        }

        Color _colour;

        public Color Colour
        {
            get { return _colour; }
            set { _colour = value; }
        }
    }
}            //    

History

  • 17th May, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Junior)
Iran (Islamic Republic of) Iran (Islamic Republic of)
he studied MCSD (C# based 2003) and MCDBA (2005) CWNA, CWNP at Sematech
IC Programming with 8051, AVR , IC desighn with FPGA and board desigh at Contronic Co

He also worked on Wireless Low level TCP/IP Programmable Module and video motion Detection algorithm
he is student of Industrial engineering in University of Payam e noor Tehran learning about PMBOK and management systems.
He has Certificate in Advanced English (CAE) and also he studied German language in ökf österreichisches Kulturforum

Comments and Discussions

 
GeneralMy vote of 5 Pin
Kanasz Robert27-Sep-12 10:52
professionalKanasz Robert27-Sep-12 10:52 
GeneralMy vote of 4 Pin
yyz176-Aug-10 20:41
yyz176-Aug-10 20:41 
GeneralAlternate version of control Pin
Lloyd (Chris) Wilson20-May-09 4:42
Lloyd (Chris) Wilson20-May-09 4:42 
GeneralRe: Alternate version of control Pin
Arash Javadi20-May-09 4:56
Arash Javadi20-May-09 4:56 
GeneralRe: Alternate version of control Pin
pianoboy1122-Feb-10 18:18
pianoboy1122-Feb-10 18:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.