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:
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. 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.
IDataGridViewEditingControl
Interface adds all functionalities for adapting your editor to datagridview
cell edit:
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;
public override Type EditType
{
get { return editType; }
}
public override Type ValueType
{
get { return valueType; }
}
public DateTime SelectedDateTime
{
get { return selectedDateTime; }
set { selectedDateTime = value; }
}
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);
}
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;
}
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)
{
}
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;
}
}
}
}
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; }
}
}
public class DataGridViewColourPickerColumn : DataGridViewColumn
{
public DataGridViewColourPickerColumn()
: base(new DataGridViewColourPickerCell())
{
}
}
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