在使用DataGridView编辑数据的时候,编辑的单元格一般会显示为文本框,逻辑值和图片会自动显示对应类型的列。当然我们自己可以手工选择列的类型,例如ComboBox列、Button列、Link列。在编辑数值和日期类型的时候,如果使用独立控件,我们会选择NumericUpDown和DataTimePicker,但在DataGridView中编辑的时候就只能用文本列。相比使用独立控件,文本框列缺少数值有效性检测,数值区间限制等功能。从本质上来看,.NET本身提供的DataGridViewCheckBoxColumn、DataGridViewComboBoxColumn之类的列,内部是集成了CheckBox和ComboBox。我们自己也可以实现类似的表格列,将独立控件添加到其中。本文就介绍如何将数值控件NumericUpDown和日期控件DateTimePicker添加到表格列中,实现自定义表格列。先上图,看看实现之后的效果:

日期列:可自定义显示格式,编辑的时候会显示DateTimePicker控件。
 
数值列:可选择显示财务账簿中的金额格式,编辑的时候显示NumericUpDown控件。
实现自定义表格列步骤如下:
1、定义要单元格编辑控件类,该类继承自要嵌入单元格的独立控件,并实现接口IDataGridViewEditingControl
2、定义单元格,继承自DataGridViewTextBoxCell,重写属性EditType(返回上一步定义的控件类型)、ValueType(返回要编辑值的类型)、DefaultNewRowValue(返回要编辑值的默认值)以及方法InitializeEditingControl(获取上一步定义的单元格编辑控件的实例,并设置实例相关属性)
3、定义表格列,继承自DataGridViewColumn,定义要设置的属性,在构造函数中设置CellTemplate属性为上一步定义的单元格的实例。重写属性CellTemplate,在set中检测value的类型必须是上一步定义的单元格类型。重写Clone方法,在其中创建当前类型的新实例,将base.Clone()获取的列实例的属性一一赋值给新实例。
 
下面是实际的代码
1、CalendarColumn(日期列)
(1)首先定义日期编辑控件,即用来编辑单元格中数值的控件。需要继承自日期控件DateTimePicker并实现IDataGridViewEditingControl接口。
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.ComponentModel; namespace CodeLibrary.Controls.DataGridViewColumns
{
[ToolboxItem(false)]
public class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl
{
public CalendarEditingControl()
: base()
{ } #region IDataGridViewEditingControl Members public object EditingControlFormattedValue
{
get { return Value.ToLongDateString(); }
set
{
var newValue = value as String;
if (newValue != null)
{
Value = DateTime.Parse(newValue);
}
}
} public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
} public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
Font = dataGridViewCellStyle.Font;
CalendarForeColor = dataGridViewCellStyle.ForeColor;
CalendarMonthBackground = dataGridViewCellStyle.BackColor;
} public int EditingControlRowIndex { get; set; } public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
{
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 false;
}
} public void PrepareEditingControlForEdit(bool selectAll)
{
} public bool RepositionEditingControlOnValueChange
{
get { return false; }
} public DataGridView EditingControlDataGridView { get; set; } public bool EditingControlValueChanged { get; set; } public Cursor EditingPanelCursor
{
get { return base.Cursor; }
} #endregion protected override void OnValueChanged(EventArgs eventargs)
{
this.EditingControlValueChanged = true;
EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnValueChanged(eventargs);
} }
}

(2)定义单元格,继承自DataGridViewTextBoxCell。在其中定义EditType为上一步定义的CalendarEditingControl,并设置ValueType为DateTime。由于在使用过程中是给列控件设置属性,例如允许设置的日期最大最小值,而实际日期限制需要修改上一步定义的编辑控件的值。所以需要在初始化编辑控件的方法中获取列的属性并给编辑控件赋值。

 using System;
using System.Windows.Forms; namespace CodeLibrary.Controls.DataGridViewColumns
{
/// <summary>
/// 日期单元格
/// </summary>
public class DataGridViewCalendarCell : DataGridViewTextBoxCell
{
/// <summary>
/// 构造函数
/// </summary>
public DataGridViewCalendarCell()
: base()
{
} /// <summary>
/// 编辑控件的类型
/// </summary>
public override Type EditType
{
get { return typeof(CalendarEditingControl); }
} /// <summary>
/// 值类型
/// </summary>
public override Type ValueType
{
get { return typeof(DateTime); }
} /// <summary>
/// 默认新值
/// </summary>
public override object DefaultNewRowValue
{
get { return DateTime.Now; }
} /// <summary>
/// 初始化编辑控件
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="initialFormattedValue"></param>
/// <param name="dataGridViewCellStyle"></param>
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
var control = DataGridView.EditingControl as CalendarEditingControl;
if (control != null)
{
if (Value != null && Value != DBNull.Value)
control.Text = Value.ToString();
DataGridViewCalendarColumn column = this.OwningColumn as DataGridViewCalendarColumn;
control.MaxDate = column.MaxDate;
control.MinDate = column.MinDate;
control.Format = DateTimePickerFormat.Custom;
control.CustomFormat = column.CustomFormat;
} } }
}

(3)定义日期列,继承自DataGridViewColumn。在构造函数中设置单元格模板为上一步定义的DataGridViewCalendarCell,实际编辑时就会显示为日期单元格。可以根据需要添加属性,例如用CustomFormat自定义日期显示格式,用MinDate、MaxDate限制日期范围。

 using System;
using System.Windows.Forms;
using System.ComponentModel; namespace CodeLibrary.Controls.DataGridViewColumns
{
/// <summary>
/// 日期列
/// </summary>
[ToolboxItem(false)]
public class DataGridViewCalendarColumn : DataGridViewColumn
{
/// <summary>
/// 构造函数
/// </summary>
public DataGridViewCalendarColumn()
: base(new DataGridViewCalendarCell())
{
this.CellTemplate = new DataGridViewCalendarCell();
} private string m_DateFormat = "D";
/// <summary>
/// 日期格式字符串
/// </summary>
[DefaultValue("D")]
[Description("获取或设置自定义日期/时间格式字符串。")]
[RefreshProperties(RefreshProperties.Repaint)]
public string CustomFormat
{
get { return m_DateFormat; }
set
{
if (m_DateFormat != value || this.CellTemplate.Style.Format != value)
{
m_DateFormat = value;
this.CellTemplate.Style.Format = this.m_DateFormat;
}
}
} private DateTime maxDate = new DateTime(, , , , , );
/// <summary>
/// 获取或设置可在控件中选择的最大日期和时间。
/// </summary>
[DefaultValue(typeof(DateTime), "12/31/9998 00:00:00")]
[Description("获取或设置可在控件中选择的最大日期和时间。")]
[RefreshProperties(RefreshProperties.Repaint)]
public DateTime MaxDate
{
get
{
return this.maxDate;
}
set
{
if (this.maxDate != value && value <= new DateTime(, , , , , ))
{
this.maxDate = value;
}
}
} private DateTime minDate = new DateTime(, , , , , );
/// <summary>
/// 获取或设置可在控件中选择的最小日期和时间。
/// </summary>
[DefaultValue(typeof(DateTime), "1/1/1753 00:00:00")]
[Description("获取或设置可在控件中选择的最小日期和时间。")]
[RefreshProperties(RefreshProperties.Repaint)]
public DateTime MinDate
{
get
{
return this.minDate;
}
set
{
if (this.minDate != value && value >= new DateTime(, , , , , ))
{
this.minDate = value;
}
}
} /// <summary>
/// 单元格模板
/// </summary>
public override DataGridViewCell CellTemplate
{
get { return base.CellTemplate; }
set
{
if (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewCalendarCell)))
{
throw new InvalidCastException("单元格模板类型不是CalendarCell或其子类。");
}
base.CellTemplate = value;
}
} /// <summary>
/// 克隆方法
/// </summary>
/// <returns></returns>
public override object Clone()
{
DataGridViewCalendarColumn column = base.Clone() as DataGridViewCalendarColumn;
column.CellTemplate = new DataGridViewCalendarCell();
column.MaxDate = this.MaxDate;
column.MinDate = this.MinDate;
column.CustomFormat = this.CustomFormat; return column;
}
}
}

2、NumericColumn(数值列)原文地址:http://www.cnblogs.com/conexpress/p/5923324.html

(1)定义编辑控件,继承自NumericUpDown并实现IDataGridViewEditingControl。

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms; namespace CodeLibrary.Controls.DataGridViewColumns
{
internal class NumericUpDownEditingControl : NumericUpDown, IDataGridViewEditingControl
{
#region Implementation of IDataGridViewEditingControl private bool editingControlValueChanged; public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
Font = dataGridViewCellStyle.Font;
ForeColor = dataGridViewCellStyle.ForeColor;
BackColor = dataGridViewCellStyle.BackColor;
} public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
switch (keyData & 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:
case Keys.Decimal:
return true;
default:
return false;
}
} public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
} public void PrepareEditingControlForEdit(bool selectAll)
{ } public DataGridView EditingControlDataGridView
{ get; set; } public object EditingControlFormattedValue
{
get { return Value.ToString(); }
set { Value = decimal.Parse(value.ToString()); }
} public int EditingControlRowIndex { get; set; } public bool EditingControlValueChanged
{
get { return editingControlValueChanged; }
set { editingControlValueChanged = value; }
} public Cursor EditingPanelCursor { get { return base.Cursor; } } public bool RepositionEditingControlOnValueChange { get { return false; } } #endregion Implementation of IDataGridViewEditingControl protected override void OnValueChanged(EventArgs eventargs)
{
editingControlValueChanged = true;
EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnValueChanged(eventargs);
} } }

(2)定义单元格控件,继承自DataGridViewTextBoxCell。为了实现会计账簿的数值显示效果,需要重写Paint方法。具体绘制涉及到GDI+相关知识,可以自行查看相关资料。

 using System;
using System.Drawing;
using System.Windows.Forms; namespace CodeLibrary.Controls.DataGridViewColumns
{
/// <summary>
/// 数值单元格
/// </summary>
internal class DataGridViewNumericCell : DataGridViewTextBoxCell
{
/// <summary>
/// 构造函数
/// </summary>
public DataGridViewNumericCell()
: base()
{
} #region 自定义绘制 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)
{
DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn;
if (column != null
&& column.ShowLine)
{
this.PaintPrivate(graphics, clipBounds, cellBounds, rowIndex,
cellState, formattedValue, errorText, cellStyle,
advancedBorderStyle, paintParts, false, false, true);
}
else
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value,
formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
}
} private bool ShouldPaintBorder(DataGridViewPaintParts paintParts)
{
return ((paintParts & DataGridViewPaintParts.Border) != DataGridViewPaintParts.None);
} private bool ShouldPaintSelectionBackground(DataGridViewPaintParts paintParts)
{
return ((paintParts & DataGridViewPaintParts.SelectionBackground) != DataGridViewPaintParts.None);
} private bool ShouldPaintBackground(DataGridViewPaintParts paintParts)
{
return ((paintParts & DataGridViewPaintParts.Background) != DataGridViewPaintParts.None);
} private bool ShouldPaintFocus(DataGridViewPaintParts paintParts)
{
return ((paintParts & DataGridViewPaintParts.Focus) != DataGridViewPaintParts.None);
} private bool ShouldPaintSelected(DataGridViewElementStates cellState)
{
return (cellState & DataGridViewElementStates.Selected) != DataGridViewElementStates.None;
} private bool ShouldPaintContentForeground(DataGridViewPaintParts paintParts)
{
return ((paintParts & DataGridViewPaintParts.ContentForeground) != DataGridViewPaintParts.None);
} protected void PaintPrivate(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
DataGridViewElementStates cellState, object formattedValue, string errorText, DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts,
bool computeContentBounds, bool computeErrorIconBounds, bool paint)
{
DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn;
CheckPaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle, paintParts, paint);
cellBounds = CalcRealCellBounds(cellBounds, advancedBorderStyle);
bool isCell = (DataGridView.CurrentCellAddress.X == base.ColumnIndex) && (DataGridView.CurrentCellAddress.Y == rowIndex) && (DataGridView.EditingControl != null);
CheckPaintBackground(graphics, cellBounds, rowIndex, cellState, cellStyle, paintParts, paint, isCell);//检查绘制背景
DrawLines(graphics, cellBounds);//绘制线条
DrawString(graphics, cellBounds, formattedValue, cellStyle, paintParts, computeContentBounds, paint, isCell);//绘制文本
} private void CheckPaintBorder(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, bool paint)
{
if (paint && ShouldPaintBorder(paintParts))//绘制边框
{
this.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
}
} private void CheckPaintBackground(Graphics graphics, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, bool paint, bool isCell)
{
SolidBrush solidBrush;
bool isCellSelected = (cellState & DataGridViewElementStates.Selected) != DataGridViewElementStates.None; if ((ShouldPaintSelectionBackground(paintParts) && isCellSelected) && !isCell)//确定绘制背景的画刷
solidBrush = new SolidBrush(cellStyle.SelectionBackColor);
else
solidBrush = new SolidBrush(cellStyle.BackColor); //绘制背景
if (paint && ShouldPaintBackground(paintParts) && cellBounds.Width > && cellBounds.Height > )
{
graphics.FillRectangle(solidBrush, cellBounds);
}
} //绘制文本
private void DrawString(Graphics graphics, Rectangle cellBounds, object formattedValue, DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, bool computeContentBounds, bool paint, bool isCell)
{
int scale = ;
string moneySymbol = "¥";
bool showMoneySymbol = true;
bool negativeShowRed = true;
int lineSpace = ; DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn; if (column != null)
{
scale = column.Scale;
moneySymbol = column.MoneySymbol.ToString();
showMoneySymbol = column.ShowMoneySymbol;
negativeShowRed = column.NegativeShowRed;
lineSpace = column.LineSpace;
} string formattedValueString = formattedValue as string;
if (!String.IsNullOrEmpty(formattedValueString) && ((paint && !isCell) || computeContentBounds) && ShouldPaintContentForeground(paintParts))
{
decimal d = ;
Decimal.TryParse(formattedValueString, out d);
bool isNegative = (d < 0M);
if (negativeShowRed && isNegative)
{
d = d * -1M;
} string format = new string('', scale);
if (scale > )
{
format = "#0." + format;
}
else
{
format = "#0";
} formattedValueString = d.ToString(format);
formattedValueString = showMoneySymbol ? moneySymbol + formattedValueString : formattedValueString; int left = cellBounds.Width;
int digitIndex = formattedValueString.Length - ;
while (left > )
{
if (digitIndex == -)
{
break;
} if (left - lineSpace > )
{
left -= lineSpace;
if (formattedValueString[digitIndex].ToString() == ".")
{
digitIndex--;
} Color foreColor = this.Selected ? cellStyle.SelectionForeColor : cellStyle.ForeColor;
foreColor = isNegative && negativeShowRed ? Color.Red : foreColor; using (SolidBrush brush = new SolidBrush(foreColor))
{
string myChar = formattedValueString[digitIndex].ToString();
SizeF myCharSize = graphics.MeasureString(myChar, cellStyle.Font);
int charLeft = cellBounds.Left + left + (int)(lineSpace - (int)myCharSize.Width) / ;
int charTop = cellBounds.Top + (int)(cellBounds.Height - (int)myCharSize.Height) / ; graphics.DrawString(myChar, cellStyle.Font, brush, charLeft, charTop);
}
}
else
{
left = ;
}
digitIndex--;
}
}
} /// <summary>
/// 计算实际单元格区间
/// </summary>
/// <param name="cellBounds">单元格区间</param>
/// <param name="advancedBorderStyle">边框风格</param>
/// <returns>实际单元格区间</returns>
private Rectangle CalcRealCellBounds(Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle)
{
Rectangle advanceRectangle = this.BorderWidths(advancedBorderStyle);
cellBounds.Offset(advanceRectangle.X, advanceRectangle.Y);
cellBounds.Width -= advanceRectangle.Right;
cellBounds.Height -= advanceRectangle.Bottom;
return cellBounds;
} //绘制线条
private void DrawLines(Graphics graphics, Rectangle cellBounds)
{
int left = cellBounds.Width;
int digitIndex = ;
int lineSpace = ;
Color DecimalPlaceColor = Color.Red;
Color ThousandsSeparatorColor = Color.DarkBlue;
Color NormalColor = Color.LightBlue; DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn;
int scale = ;
if (column != null)
{
scale = column.Scale;
lineSpace = column.LineSpace;
}
Point PointStart, PointEnd; while (left > )
{
if (left - lineSpace > )
{
left -= lineSpace;
PointStart = new Point(cellBounds.Left + left, cellBounds.Top);
PointEnd = new Point(cellBounds.Left + left, cellBounds.Top + cellBounds.Height); if (digitIndex == scale)
{
using (Pen redPen = new Pen(DecimalPlaceColor, 1.0F))//绘制小数线
graphics.DrawLine(redPen, PointStart, PointEnd);
}
else
{
if (digitIndex > scale && (digitIndex - scale) % == )//绘制千分位线
{
using (Pen specialPen = new Pen(ThousandsSeparatorColor, 2.0F))
graphics.DrawLine(specialPen, PointStart, PointEnd);
}
else
{
using (Pen normalPen = new Pen(NormalColor, 1.0F))//绘制普通线
graphics.DrawLine(normalPen, PointStart, PointEnd);
}
}
}
else
{
left = ;
}
digitIndex++;
}
} #endregion 自定义绘制 /// <summary>
/// 编辑类型
/// </summary>
public override Type EditType
{
get { return typeof(NumericUpDownEditingControl); }
} /// <summary>
/// 值类型
/// </summary>
public override Type ValueType
{
get { return typeof(decimal); }
} /// <summary>
/// 默认值
/// </summary>
public override object DefaultNewRowValue
{
get { return 0M; }
} /// <summary>
/// 初始化编辑控件
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="initialFormattedValue"></param>
/// <param name="dataGridViewCellStyle"></param>
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
NumericUpDownEditingControl num = this.DataGridView.EditingControl as NumericUpDownEditingControl;
if (num != null)
{
DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn;
num.DecimalPlaces = column.Scale;
num.ThousandsSeparator = true;
num.Minimum = column.Minimum;
num.Maximum = column.Maximum;
if(this.Value != null && this.Value != DBNull.Value)
num.Value = Convert.ToDecimal(this.Value);
}
} }//class FinanceTextBoxCell }//namespace

(3)定义列,继承自DataGridViewColumn。由于要支持会计账簿的数值显示效果,添加了很多控制显示效果的属性。

 using System;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel; namespace CodeLibrary.Controls.DataGridViewColumns
{ /// <summary>
/// 数值列
/// </summary>
[ToolboxItem(false)]
public class DataGridViewNumericColumn : DataGridViewColumn
{
#region Fields and properties private bool showLine = false;
/// <summary>
/// 是否显示账本线条
/// </summary>
[DefaultValue(false)]
[Description("指示是否显示账本线条。")]
[RefreshProperties(RefreshProperties.Repaint)]
public bool ShowLine
{
get { return this.showLine; }
set
{
if (this.showLine != value)
{
this.showLine = value;
}
}
} private int lineSpace = ;
/// <summary>
/// 线间隔
/// </summary>
[DefaultValue()]
[Description("线间隔。")]
[RefreshProperties(RefreshProperties.Repaint)]
public int LineSpace
{
get { return lineSpace; }
set
{
if (value <= || value >= this.Width)
throw new ArgumentOutOfRangeException("线间隔必须大于零且小于列宽度。");
else
{
if (value != this.lineSpace)
{
lineSpace = value;
}
}
}
} private Color decimalPlaceColor = Color.Red;
/// <summary>
/// 小数位分隔线颜色
/// </summary>
[DefaultValue(typeof(Color), "Red")]
[Description("小数位分隔线颜色。")]
[RefreshProperties(RefreshProperties.Repaint)]
public Color DecimalPlaceColor
{
get { return decimalPlaceColor; }
set
{
if (decimalPlaceColor != value)
decimalPlaceColor = value;
}
} private Color thousandsSeparatorColor = Color.DarkBlue;
/// <summary>
/// 千位分隔线颜色
/// </summary>
[DefaultValue(typeof(Color), "DarkBlue")]
[Description("千位分隔线颜色。")]
[RefreshProperties(RefreshProperties.Repaint)]
public Color ThousandsSeparatorColor
{
get { return thousandsSeparatorColor; }
set
{
if (thousandsSeparatorColor != value)
{
thousandsSeparatorColor = value;
}
}
} private Color normalColor = Color.LightBlue;
/// <summary>
/// 普通分隔线颜色
/// </summary>
[DefaultValue(typeof(Color), "LightBlue")]
[Description("普通分隔线颜色。")]
[RefreshProperties(RefreshProperties.Repaint)]
public Color NormalColor
{
get { return normalColor; }
set
{
if (normalColor != value)
normalColor = value;
}
} private int scale = ;
/// <summary>
/// 小数位数
/// </summary>
[DefaultValue()]
[Description("小数位数。")]
[RefreshProperties(RefreshProperties.Repaint)]
public int Scale
{
get { return scale; }
set
{
if (value < )
throw new ArgumentOutOfRangeException("小数位数不允许小于零。");
else
scale = value;
}
} private bool negativeShowRed = true;
/// <summary>
/// 负数显示红字
/// </summary>
[DefaultValue(true)]
[Description("指示负数是否显示红字。")]
[RefreshProperties(RefreshProperties.Repaint)]
public bool NegativeShowRed
{
get { return negativeShowRed; }
set
{
if (negativeShowRed != value)
negativeShowRed = value;
}
} private char moneySymbol = '¥';
/// <summary>
/// 货币符号
/// </summary>
[DefaultValue('¥')]
[Description("货币符号。")]
[RefreshProperties(RefreshProperties.Repaint)]
public char MoneySymbol
{
get { return moneySymbol; }
set { moneySymbol = value; }
} private bool showMoneySymbol = true;
/// <summary>
/// 是否显示货币符号,仅当ShowLine属性为true时有效。
/// </summary>
[DefaultValue(true)]
[Description("是否显示货币符号。")]
[RefreshProperties(RefreshProperties.Repaint)]
public bool ShowMoneySymbol
{
get { return showMoneySymbol; }
set
{
if (showMoneySymbol != value)
showMoneySymbol = value;
}
} private decimal minimum = -99999999999M;
/// <summary>
/// 最小值
/// </summary>
[DefaultValue(typeof(decimal), "-99999999999")]
[Description("最小值。")]
[RefreshProperties(RefreshProperties.Repaint)]
public decimal Minimum
{
get { return minimum; }
set
{
if (value >= maximum)
throw new ArgumentOutOfRangeException("最小值必须小于最大值。");
else
minimum = value;
}
} private decimal maximum = 99999999999M;
/// <summary>
/// 最大值
/// </summary>
[DefaultValue(typeof(decimal), "")]
[Description("最大值。")]
[RefreshProperties(RefreshProperties.Repaint)]
public decimal Maximum
{
get { return maximum; }
set
{
if (value <= minimum)
throw new ArgumentOutOfRangeException("最大值必须大于最小值。");
else
maximum = value;
}
} private HorizontalAlignment editTextAlign = HorizontalAlignment.Left;
/// <summary>
/// 指示编辑时文本在编辑框中的对齐方式
/// </summary>
[DefaultValue(HorizontalAlignment.Left)]
[Description("指示编辑时文本在编辑框中的对齐方式。")]
[RefreshProperties(RefreshProperties.Repaint)]
public HorizontalAlignment EditTextAlign
{
get { return editTextAlign; }
set { editTextAlign = value; }
} /// <summary>
/// 单元格模板
/// </summary>
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
if (value == null || (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewNumericCell))))
throw new ArgumentException("单元格模板类型不是FinanceCell或其子类。");
else
base.CellTemplate = value;
}
} #endregion Fields and properties /// <summary>
/// 数值列
/// </summary>
public DataGridViewNumericColumn()
: base()
{
this.CellTemplate = new DataGridViewNumericCell();
} /// <summary>
/// 重写克隆方法
/// </summary>
/// <returns></returns>
public override object Clone()
{
DataGridViewNumericColumn column = (DataGridViewNumericColumn)base.Clone();
column.CellTemplate = new DataGridViewNumericCell();
column.DecimalPlaceColor = this.DecimalPlaceColor;
column.LineSpace = this.LineSpace;
column.MoneySymbol = this.MoneySymbol;
column.NegativeShowRed = this.NegativeShowRed;
column.NormalColor = this.NormalColor;
column.Scale = this.Scale;
column.ShowMoneySymbol = this.ShowMoneySymbol;
column.ShowLine = this.ShowLine;
column.ThousandsSeparatorColor = this.ThousandsSeparatorColor;
column.EditTextAlign = this.EditTextAlign;
return column;
} } }

实际使用过程中,将控件添加到工具箱中。给DataGridView添加列的时候,下拉选择列的类型,就可以看到自定义的列了。

在实现自定义列的过程中可以根据需要添加相关的控制属性,例如限制输入值的范围、显示效果控制等。在理解实现自定义列的方法之后,就可以实现更多个性化的列。

代码下载地址:http://files.cnblogs.com/files/conexpress/DataGridViewColumns.zip

相关文章

.NET组件控件实例编程系列——5.DataGridView数值列和日期列的更多相关文章

  1. VS2010/MFC编程入门之二十三(常用控件:按钮控件的编程实例)

    上一节VS2010/MFC编程入门教程中鸡啄米讲了按钮控件Button.Radio Button和Check Box的基本用法,本节就继续讲按钮控件的内容,通过一个实例让大家更清楚按钮控件在实际的软件 ...

  2. MFC编程入门之二十三(常用控件:按钮控件的编程实例)

    上一节讲了按钮控件Button.Radio Button和Check Box的基本用法,本节继续讲按钮控件的内容,通过一个实例让大家更清楚按钮控件在实际的软件开发中如何使用. 因为Button控件在前 ...

  3. VS2010-MFC(常用控件:按钮控件的编程实例)

    转自:http://www.jizhuomi.com/software/184.html 因为Button控件在前面的例子中涉及到了,比较简单,本文就不作深入分析了,而是重点讲解单选按钮Radio B ...

  4. ASP.NET2.0组件控件开发视频 初体验

    原文:ASP.NET2.0组件控件开发视频 初体验 ASP.NET2.0组件控件开发视频 初体验 录了视频,质量不是很好,大家体验下.我会重新录制的 如果不清楚,可以看看http://v.youku. ...

  5. Android各组件/控件间通信利器之EventBus

    实际项目开发过程中,经常遇到如下场景:不同的应用程序组件的控件间具有一定的相互关联性,其中用户对后者进行的某种操作会引起前者的相应改变.举一个具体的场景:以糗事百科为例,在糗事列表页和详情页页,对于每 ...

  6. MFC控件GDI编程

    MFC控件GDI编程 一丶学习内容 1.了解常用的GDI函数绘图. 2.使用常用的画笔画刷. 二丶常用的GDI函数绘图 上方则为我们常用的GDI函数了. 画线 矩形. 以及圆 等等. 2.1 画线代码 ...

  7. 计数器控件实例 NumericStepper

    计数器控件实例 书:158 <?xml version="1.0" encoding="utf-8"?> <s:Application xml ...

  8. 树结构控件实例 TreeControl

    树结构控件实例 书:157 <?xml version="1.0" encoding="utf-8"?> <s:Application xml ...

  9. 下拉列表控件实例 ComboBoxControl

    下拉列表控件实例 书:151页 <?xml version="1.0" encoding="utf-8"?> <s:Application x ...

随机推荐

  1. Python实战:扫描key完整性

    之前在国际版本中,需要支持中英文切换功能,在如此繁多的源文件里要查找源文件里的key是语言资源包是否对应. 正好运用在之前学的python,写了个工具,支持自定义替换标签,批量处理源文件.现在看来,效 ...

  2. Unity_Shader(1)

    Shader需要作用在Material中才能起作用. 例子1: (1)创建Shader 将shader替换为以下代码: Shader"MyDir/FirstShader" { Su ...

  3. 【5集iCore3_ADP演示视频】5-1 iCore3应用开发平台开箱视频

    iCore3双核心应用开发平台基于iCore3双核心板,包含ARM.FPGA.7寸液晶屏.双通道数字示波器.任意波发生器.电压表等模块,是一款专为电子爱好者设计的综合性电子学习系统. [视频简介]本视 ...

  4. php上传大文件,提示出错

  5. equals和==的区别

    ---恢复内容开始--- equals:用于判断两个变量是否是对同一个对象的引用,即堆中的内容是否相同. 1.第一:对象不同,内容相同: ==:等于.比较两个地址是不是一样的(地址一样值肯定一样)(比 ...

  6. office 365 online api

    https://view.officeapps.live.com/op/view.aspx?src=http://bookfuns.com/1.ppt

  7. jquery的each()详细介绍

    each()方法能使DOM循环结构简洁,不容易出错.each()函数封装了十分强大的遍历功能,使用也很方便,它可以遍历一维数组.多维数组.DOM, JSON 等等在javaScript开发过程中使用$ ...

  8. Android界面组件的四种启动方式

    Android界面组件启动有四种方式 standard,singleTop,singleTask,singleInstance. standard:每次调用都会都会产生新的组件. singletop: ...

  9. GIT使用笔记-fatal:multiple stage entries for merged file处理办法

    该错误是在cherry-pick时出现 无法确定冲突原因 分支无法checkout ,reset等等全都失效 在网上给出的解决办法全部都是 rm .git/index git add -A git c ...

  10. wordpres 自定义comment样式

    http://wange.im/diy-wordpress-comment-style.html function mytheme_comment($comment, $args, $depth) { ...