首页 > 代码库 > .NET组件控件实例编程系列——5.DataGridView数值列和日期列

.NET组件控件实例编程系列——5.DataGridView数值列和日期列

在使用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接口。
 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Windows.Forms; 5 using System.ComponentModel; 6  7 namespace CodeLibrary.Controls.DataGridViewColumns 8 { 9     [ToolboxItem(false)]10     public class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl11     {12         public CalendarEditingControl()13             : base()14         { }15 16         #region IDataGridViewEditingControl Members17 18         public object EditingControlFormattedValue19         {20             get { return Value.ToLongDateString(); }21             set22             {23                 var newValue = http://www.mamicode.com/value as String;24                 if (newValue != null)25                 {26                     Value =http://www.mamicode.com/ DateTime.Parse(newValue);27                 }28             }29         }30 31         public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)32         {33             return EditingControlFormattedValue;34         }35 36         public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)37         {38             Font = dataGridViewCellStyle.Font;39             CalendarForeColor = dataGridViewCellStyle.ForeColor;40             CalendarMonthBackground = dataGridViewCellStyle.BackColor;41         }42 43         public int EditingControlRowIndex { get; set; }44 45         public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)46         {47             switch (key & Keys.KeyCode)48             {49                 case Keys.Left:50                 case Keys.Up:51                 case Keys.Down:52                 case Keys.Right:53                 case Keys.Home:54                 case Keys.End:55                 case Keys.PageDown:56                 case Keys.PageUp:57                     return true;58                 default:59                     return false;60             }61         }62 63         public void PrepareEditingControlForEdit(bool selectAll)64         {65         }66 67         public bool RepositionEditingControlOnValueChange68         {69             get { return false; }70         }71 72         public DataGridView EditingControlDataGridView { get; set; }73 74         public bool EditingControlValueChanged { get; set; }75 76         public Cursor EditingPanelCursor77         {78             get { return base.Cursor; }79         }80 81         #endregion82 83         protected override void OnValueChanged(EventArgs eventargs)84         {85             this.EditingControlValueChanged = true;86             EditingControlDataGridView.NotifyCurrentCellDirty(true);87             base.OnValueChanged(eventargs);88         }89 90     }91 }

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

 1 using System; 2 using System.Windows.Forms; 3  4 namespace CodeLibrary.Controls.DataGridViewColumns 5 { 6     /// <summary> 7     /// 日期单元格 8     /// </summary> 9     public class DataGridViewCalendarCell : DataGridViewTextBoxCell10     {11         /// <summary>12         /// 构造函数13         /// </summary>14         public DataGridViewCalendarCell()15             : base()16         {17         }18 19         /// <summary>20         /// 编辑控件的类型21         /// </summary>22         public override Type EditType23         {24             get { return typeof(CalendarEditingControl); }25         }26 27         /// <summary>28         /// 值类型29         /// </summary>30         public override Type ValueType31         {32             get { return typeof(DateTime); }33         }34 35         /// <summary>36         /// 默认新值37         /// </summary>38         public override object DefaultNewRowValue39         {40             get { return DateTime.Now; }41         }42 43         /// <summary>44         /// 初始化编辑控件45         /// </summary>46         /// <param name="rowIndex"></param>47         /// <param name="initialFormattedValue"></param>48         /// <param name="dataGridViewCellStyle"></param>49         public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)50         {51             base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);52             var control = DataGridView.EditingControl as CalendarEditingControl;53             if (control != null)54             {55                 if (Value != null && Value != DBNull.Value)56                     control.Text = Value.ToString();57                 DataGridViewCalendarColumn column = this.OwningColumn as DataGridViewCalendarColumn;58                 control.MaxDate = column.MaxDate;59                 control.MinDate = column.MinDate;60                 control.Format = DateTimePickerFormat.Custom;61                 control.CustomFormat = column.CustomFormat;62             }63 64         }65 66     }67 }

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

  1 using System;  2 using System.Windows.Forms;  3 using System.ComponentModel;  4   5 namespace CodeLibrary.Controls.DataGridViewColumns  6 {  7     /// <summary>  8     /// 日期列  9     /// </summary> 10     [ToolboxItem(false)] 11     public class DataGridViewCalendarColumn : DataGridViewColumn 12     { 13         /// <summary> 14         /// 构造函数 15         /// </summary> 16         public DataGridViewCalendarColumn() 17             : base(new DataGridViewCalendarCell()) 18         { 19             this.CellTemplate = new DataGridViewCalendarCell(); 20         } 21  22         private string m_DateFormat = "D"; 23         /// <summary> 24         /// 日期格式字符串 25         /// </summary> 26         [DefaultValue("D")] 27         [Description("获取或设置自定义日期/时间格式字符串。")] 28         [RefreshProperties(RefreshProperties.Repaint)] 29         public string CustomFormat 30         { 31             get { return m_DateFormat; } 32             set 33             { 34                 if (m_DateFormat != value || this.CellTemplate.Style.Format != value) 35                 { 36                     m_DateFormat = value; 37                     this.CellTemplate.Style.Format = this.m_DateFormat; 38                 } 39             } 40         } 41  42         private DateTime maxDate = new DateTime(9998, 12, 31, 0, 0, 0); 43         /// <summary> 44         /// 获取或设置可在控件中选择的最大日期和时间。 45         /// </summary> 46         [DefaultValue(typeof(DateTime), "12/31/9998 00:00:00")] 47         [Description("获取或设置可在控件中选择的最大日期和时间。")] 48         [RefreshProperties(RefreshProperties.Repaint)] 49         public DateTime MaxDate 50         { 51             get 52             { 53                 return this.maxDate; 54             } 55             set 56             { 57                 if (this.maxDate != value && value <= new DateTime(9998, 12, 31, 0, 0, 0)) 58                 { 59                     this.maxDate = value; 60                 } 61             } 62         } 63  64         private DateTime minDate = new DateTime(1753, 1, 1, 0, 0, 0); 65         /// <summary> 66         /// 获取或设置可在控件中选择的最小日期和时间。 67         /// </summary> 68         [DefaultValue(typeof(DateTime), "1/1/1753 00:00:00")] 69         [Description("获取或设置可在控件中选择的最小日期和时间。")] 70         [RefreshProperties(RefreshProperties.Repaint)] 71         public DateTime MinDate 72         { 73             get 74             { 75                 return this.minDate; 76             } 77             set 78             { 79                 if (this.minDate != value && value >= new DateTime(1753, 1, 1, 0, 0, 0)) 80                 { 81                     this.minDate = value; 82                 } 83             } 84         } 85  86         /// <summary> 87         /// 单元格模板 88         /// </summary> 89         public override DataGridViewCell CellTemplate 90         { 91             get { return base.CellTemplate; } 92             set 93             { 94                 if (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewCalendarCell))) 95                 { 96                     throw new InvalidCastException("单元格模板类型不是CalendarCell或其子类。"); 97                 } 98                 base.CellTemplate = value; 99             }100         }101 102         /// <summary>103         /// 克隆方法104         /// </summary>105         /// <returns></returns>106         public override object Clone()107         {108             DataGridViewCalendarColumn column = base.Clone() as DataGridViewCalendarColumn;109             column.CellTemplate = new DataGridViewCalendarCell();110             column.MaxDate = this.MaxDate;111             column.MinDate = this.MinDate;112             column.CustomFormat = this.CustomFormat;113 114             return column;115         }116     }117 }

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

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

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Windows.Forms; 6  7 namespace CodeLibrary.Controls.DataGridViewColumns 8 { 9     internal class NumericUpDownEditingControl : NumericUpDown, IDataGridViewEditingControl10     {11         #region Implementation of IDataGridViewEditingControl12 13         private bool editingControlValueChanged;14 15         public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)16         {17             Font = dataGridViewCellStyle.Font;18             ForeColor = dataGridViewCellStyle.ForeColor;19             BackColor = dataGridViewCellStyle.BackColor;20         }21 22         public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)23         {24             switch (keyData & Keys.KeyCode)25             {26                 case Keys.Left:27                 case Keys.Up:28                 case Keys.Down:29                 case Keys.Right:30                 case Keys.Home:31                 case Keys.End:32                 case Keys.PageDown:33                 case Keys.PageUp:34                 case Keys.Decimal:35                     return true;36                 default:37                     return false;38             }39         }40 41         public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)42         {43             return EditingControlFormattedValue;44         }45 46         public void PrepareEditingControlForEdit(bool selectAll)47         { }48 49         public DataGridView EditingControlDataGridView50         { get; set; }51 52         public object EditingControlFormattedValue53         {54             get { return Value.ToString(); }55             set { Value = http://www.mamicode.com/decimal.Parse(value.ToString()); }56         }57 58         public int EditingControlRowIndex { get; set; }59 60         public bool EditingControlValueChanged61         {62             get { return editingControlValueChanged; }63             set { editingControlValueChanged = value; }64         }65 66         public Cursor EditingPanelCursor { get { return base.Cursor; } }67 68         public bool RepositionEditingControlOnValueChange { get { return false; } }69 70         #endregion Implementation of IDataGridViewEditingControl71 72         protected override void OnValueChanged(EventArgs eventargs)73         {74             editingControlValueChanged = true;75             EditingControlDataGridView.NotifyCurrentCellDirty(true);76             base.OnValueChanged(eventargs);77         }78 79     }80 81 }

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

  1 using System;  2 using System.Drawing;  3 using System.Windows.Forms;  4   5   6 namespace CodeLibrary.Controls.DataGridViewColumns  7 {  8     /// <summary>  9     /// 数值单元格 10     /// </summary> 11     internal class DataGridViewNumericCell : DataGridViewTextBoxCell 12     { 13         /// <summary> 14         /// 构造函数 15         /// </summary> 16         public DataGridViewNumericCell() 17             : base() 18         { 19         } 20  21         #region 自定义绘制 22  23         protected override void Paint(Graphics graphics, Rectangle clipBounds, 24             Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, 25             object value, object formattedValue, string errorText, 26             DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, 27             DataGridViewPaintParts paintParts) 28         { 29             DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn; 30             if (column != null 31                 && column.ShowLine) 32             { 33                 this.PaintPrivate(graphics, clipBounds, cellBounds, rowIndex, 34                     cellState, formattedValue, errorText, cellStyle, 35                     advancedBorderStyle, paintParts, false, false, true); 36             } 37             else 38             { 39                 base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value,  40                     formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); 41             } 42         } 43  44         private bool ShouldPaintBorder(DataGridViewPaintParts paintParts) 45         { 46             return ((paintParts & DataGridViewPaintParts.Border) != DataGridViewPaintParts.None); 47         } 48  49         private bool ShouldPaintSelectionBackground(DataGridViewPaintParts paintParts) 50         { 51             return ((paintParts & DataGridViewPaintParts.SelectionBackground) != DataGridViewPaintParts.None); 52         } 53  54         private bool ShouldPaintBackground(DataGridViewPaintParts paintParts) 55         { 56             return ((paintParts & DataGridViewPaintParts.Background) != DataGridViewPaintParts.None); 57         } 58  59         private bool ShouldPaintFocus(DataGridViewPaintParts paintParts) 60         { 61             return ((paintParts & DataGridViewPaintParts.Focus) != DataGridViewPaintParts.None); 62         } 63  64         private bool ShouldPaintSelected(DataGridViewElementStates cellState) 65         { 66             return (cellState & DataGridViewElementStates.Selected) != DataGridViewElementStates.None; 67         } 68  69         private bool ShouldPaintContentForeground(DataGridViewPaintParts paintParts) 70         { 71             return ((paintParts & DataGridViewPaintParts.ContentForeground) != DataGridViewPaintParts.None); 72         } 73  74         protected void PaintPrivate(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,  75             DataGridViewElementStates cellState, object formattedValue, string errorText, DataGridViewCellStyle cellStyle,  76             DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts,  77             bool computeContentBounds, bool computeErrorIconBounds, bool paint) 78         { 79             DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn; 80             CheckPaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle, paintParts, paint); 81             cellBounds = CalcRealCellBounds(cellBounds, advancedBorderStyle); 82             bool isCell = (DataGridView.CurrentCellAddress.X == base.ColumnIndex) && (DataGridView.CurrentCellAddress.Y == rowIndex) && (DataGridView.EditingControl != null); 83             CheckPaintBackground(graphics, cellBounds, rowIndex, cellState, cellStyle, paintParts, paint, isCell);//检查绘制背景 84             DrawLines(graphics, cellBounds);//绘制线条 85             DrawString(graphics, cellBounds, formattedValue, cellStyle, paintParts, computeContentBounds, paint, isCell);//绘制文本 86         } 87  88         private void CheckPaintBorder(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, bool paint) 89         { 90             if (paint && ShouldPaintBorder(paintParts))//绘制边框 91             { 92                 this.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); 93             } 94         } 95  96         private void CheckPaintBackground(Graphics graphics, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, bool paint, bool isCell) 97         { 98             SolidBrush solidBrush; 99             bool isCellSelected = (cellState & DataGridViewElementStates.Selected) != DataGridViewElementStates.None;100 101             if ((ShouldPaintSelectionBackground(paintParts) && isCellSelected) && !isCell)//确定绘制背景的画刷102                 solidBrush = new SolidBrush(cellStyle.SelectionBackColor);103             else104                 solidBrush = new SolidBrush(cellStyle.BackColor);105 106             //绘制背景107             if (paint && ShouldPaintBackground(paintParts) && cellBounds.Width > 0 && cellBounds.Height > 0)108             {109                 graphics.FillRectangle(solidBrush, cellBounds);110             }111         }112 113         //绘制文本114         private void DrawString(Graphics graphics, Rectangle cellBounds, object formattedValue, DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, bool computeContentBounds, bool paint, bool isCell)115         {116             int scale = 2;117             string moneySymbol = "";118             bool showMoneySymbol = true;119             bool negativeShowRed = true;120             int lineSpace = 12;121 122             DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn;123             124             if (column != null)125             {126                 scale = column.Scale;127                 moneySymbol = column.MoneySymbol.ToString();128                 showMoneySymbol = column.ShowMoneySymbol;129                 negativeShowRed = column.NegativeShowRed;130                 lineSpace = column.LineSpace;131             }132 133             string formattedValueString = formattedValue as string;134             if (!String.IsNullOrEmpty(formattedValueString) && ((paint && !isCell) || computeContentBounds) && ShouldPaintContentForeground(paintParts))135             {136                 decimal d = 0;137                 Decimal.TryParse(formattedValueString, out d);138                 bool isNegative = (d < 0M);139                 if (negativeShowRed && isNegative)140                 {141                     d = d * -1M;142                 }143 144                 string format = new string(0, scale);145                 if (scale > 0)146                 {147                     format = "#0." + format;148                 }149                 else150                 {151                     format = "#0";152                 }153 154                 formattedValueString = d.ToString(format);155                 formattedValueString = showMoneySymbol ? moneySymbol + formattedValueString : formattedValueString;156 157                 int left = cellBounds.Width;158                 int digitIndex = formattedValueString.Length - 1;159                 while (left > 0)160                 {161                     if (digitIndex == -1)162                     {163                         break;164                     }165 166                     if (left - lineSpace > 0)167                     {168                         left -= lineSpace;169                         if (formattedValueString[digitIndex].ToString() == ".")170                         {171                             digitIndex--;172                         }173 174                         Color foreColor = this.Selected ? cellStyle.SelectionForeColor : cellStyle.ForeColor;175                         foreColor = isNegative && negativeShowRed ? Color.Red : foreColor;176 177                         using (SolidBrush brush = new SolidBrush(foreColor))178                         {179                             string myChar = formattedValueString[digitIndex].ToString();180                             SizeF myCharSize = graphics.MeasureString(myChar, cellStyle.Font);181                             int charLeft = cellBounds.Left + left + (int)(lineSpace - (int)myCharSize.Width) / 2;182                             int charTop = cellBounds.Top + (int)(cellBounds.Height - (int)myCharSize.Height) / 2;183 184                             graphics.DrawString(myChar, cellStyle.Font, brush, charLeft, charTop);185                         }186                     }187                     else188                     {189                         left = 0;190                     }191                     digitIndex--;192                 }193             }194         }195 196         /// <summary>197         /// 计算实际单元格区间198         /// </summary>199         /// <param name="cellBounds">单元格区间</param>200         /// <param name="advancedBorderStyle">边框风格</param>201         /// <returns>实际单元格区间</returns>202         private Rectangle CalcRealCellBounds(Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle)203         {204             Rectangle advanceRectangle = this.BorderWidths(advancedBorderStyle);205             cellBounds.Offset(advanceRectangle.X, advanceRectangle.Y);206             cellBounds.Width -= advanceRectangle.Right;207             cellBounds.Height -= advanceRectangle.Bottom;208             return cellBounds;209         }210 211         //绘制线条212         private void DrawLines(Graphics graphics, Rectangle cellBounds)213         {214             int left = cellBounds.Width;215             int digitIndex = 1;216             int lineSpace = 12;217             Color DecimalPlaceColor = Color.Red;218             Color ThousandsSeparatorColor = Color.DarkBlue;219             Color NormalColor = Color.LightBlue;220 221             DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn;222             int scale = 2;223             if (column != null)224             {225                 scale = column.Scale;226                 lineSpace = column.LineSpace;227             }228             Point PointStart, PointEnd;229 230             while (left > 0)231             {232                 if (left - lineSpace > 0)233                 {234                     left -= lineSpace;235                     PointStart = new Point(cellBounds.Left + left, cellBounds.Top);236                     PointEnd = new Point(cellBounds.Left + left, cellBounds.Top + cellBounds.Height);237 238                     if (digitIndex == scale)239                     {240                         using (Pen redPen = new Pen(DecimalPlaceColor, 1.0F))//绘制小数线241                             graphics.DrawLine(redPen, PointStart, PointEnd);242                     }243                     else244                     {245                         if (digitIndex > scale && (digitIndex - scale) % 3 == 0)//绘制千分位线246                         {247                             using (Pen specialPen = new Pen(ThousandsSeparatorColor, 2.0F))248                                 graphics.DrawLine(specialPen, PointStart, PointEnd);249                         }250                         else251                         {252                             using (Pen normalPen = new Pen(NormalColor, 1.0F))//绘制普通线253                                 graphics.DrawLine(normalPen, PointStart, PointEnd);254                         }255                     }256                 }257                 else258                 {259                     left = 0;260                 }261                 digitIndex++;262             }263         }264 265         #endregion 自定义绘制266 267         /// <summary>268         /// 编辑类型269         /// </summary>270         public override Type EditType271         {272             get { return typeof(NumericUpDownEditingControl); }273         }274 275         /// <summary>276         /// 值类型277         /// </summary>278         public override Type ValueType279         {280             get { return typeof(decimal); }281         }282 283         /// <summary>284         /// 默认值285         /// </summary>286         public override object DefaultNewRowValue287         {288             get { return 0M; }289         }290 291         /// <summary>292         /// 初始化编辑控件293         /// </summary>294         /// <param name="rowIndex"></param>295         /// <param name="initialFormattedValue"></param>296         /// <param name="dataGridViewCellStyle"></param>297         public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)298         {299             base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);300             NumericUpDownEditingControl num = this.DataGridView.EditingControl as NumericUpDownEditingControl;301             if (num != null)302             {303                 DataGridViewNumericColumn column = this.OwningColumn as DataGridViewNumericColumn;304                 num.DecimalPlaces = column.Scale;305                 num.ThousandsSeparator = true;306                 num.Minimum = column.Minimum;307                 num.Maximum = column.Maximum;308                 if(this.Value != null && this.Value != DBNull.Value)309                     num.Value = http://www.mamicode.com/Convert.ToDecimal(this.Value);310             }311         }312 313     }//class FinanceTextBoxCell314 315 }//namespace

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

  1 using System;  2 using System.Windows.Forms;  3 using System.Drawing;  4 using System.ComponentModel;  5   6 namespace CodeLibrary.Controls.DataGridViewColumns  7 {  8   9     /// <summary> 10     /// 数值列 11     /// </summary> 12     [ToolboxItem(false)] 13     public class DataGridViewNumericColumn : DataGridViewColumn 14     { 15         #region Fields and properties 16  17         private bool showLine = false; 18         /// <summary> 19         /// 是否显示账本线条 20         /// </summary> 21         [DefaultValue(false)] 22         [Description("指示是否显示账本线条。")] 23         [RefreshProperties(RefreshProperties.Repaint)] 24         public bool ShowLine 25         { 26             get { return this.showLine; } 27             set 28             { 29                 if (this.showLine != value) 30                 { 31                     this.showLine = value; 32                 } 33             } 34         } 35  36         private int lineSpace = 12; 37         /// <summary> 38         /// 线间隔 39         /// </summary> 40         [DefaultValue(12)] 41         [Description("线间隔。")] 42         [RefreshProperties(RefreshProperties.Repaint)] 43         public int LineSpace 44         { 45             get { return lineSpace; } 46             set 47             { 48                 if (value <= 0 || value >= this.Width) 49                     throw new ArgumentOutOfRangeException("线间隔必须大于零且小于列宽度。"); 50                 else 51                 { 52                     if (value != this.lineSpace) 53                     { 54                         lineSpace = value; 55                     } 56                 } 57             } 58         } 59  60         private Color decimalPlaceColor = Color.Red; 61         /// <summary> 62         /// 小数位分隔线颜色 63         /// </summary> 64         [DefaultValue(typeof(Color), "Red")] 65         [Description("小数位分隔线颜色。")] 66         [RefreshProperties(RefreshProperties.Repaint)] 67         public Color DecimalPlaceColor 68         { 69             get { return decimalPlaceColor; } 70             set 71             { 72                 if (decimalPlaceColor != value) 73                     decimalPlaceColor = value; 74             } 75         } 76  77         private Color thousandsSeparatorColor = Color.DarkBlue; 78         /// <summary> 79         /// 千位分隔线颜色 80         /// </summary> 81         [DefaultValue(typeof(Color), "DarkBlue")] 82         [Description("千位分隔线颜色。")] 83         [RefreshProperties(RefreshProperties.Repaint)] 84         public Color ThousandsSeparatorColor 85         { 86             get { return thousandsSeparatorColor; } 87             set 88             { 89                 if (thousandsSeparatorColor != value) 90                 { 91                     thousandsSeparatorColor = value; 92                 } 93             } 94         } 95  96         private Color normalColor = Color.LightBlue; 97         /// <summary> 98         /// 普通分隔线颜色 99         /// </summary>100         [DefaultValue(typeof(Color), "LightBlue")]101         [Description("普通分隔线颜色。")]102         [RefreshProperties(RefreshProperties.Repaint)]103         public Color NormalColor104         {105             get { return normalColor; }106             set107             {108                 if (normalColor != value)109                     normalColor = value;110             }111         }112 113         private int scale = 2;114         /// <summary>115         /// 小数位数116         /// </summary>117         [DefaultValue(2)]118         [Description("小数位数。")]119         [RefreshProperties(RefreshProperties.Repaint)]120         public int Scale121         {122             get { return scale; }123             set124             {125                 if (value < 0)126                     throw new ArgumentOutOfRangeException("小数位数不允许小于零。");127                 else128                     scale = value;129             }130         }131 132         private bool negativeShowRed = true;133         /// <summary>134         /// 负数显示红字135         /// </summary>136         [DefaultValue(true)]137         [Description("指示负数是否显示红字。")]138         [RefreshProperties(RefreshProperties.Repaint)]139         public bool NegativeShowRed140         {141             get { return negativeShowRed; }142             set143             {144                 if (negativeShowRed != value)145                     negativeShowRed = value;146             }147         }148 149         private char moneySymbol = ;150         /// <summary>151         /// 货币符号152         /// </summary>153         [DefaultValue()]154         [Description("货币符号。")]155         [RefreshProperties(RefreshProperties.Repaint)]156         public char MoneySymbol157         {158             get { return moneySymbol; }159             set { moneySymbol = value; }160         }161 162         private bool showMoneySymbol = true;163         /// <summary>164         /// 是否显示货币符号,仅当ShowLine属性为true时有效。165         /// </summary>166         [DefaultValue(true)]167         [Description("是否显示货币符号。")]168         [RefreshProperties(RefreshProperties.Repaint)]169         public bool ShowMoneySymbol170         {171             get { return showMoneySymbol; }172             set173             {174                 if (showMoneySymbol != value)175                     showMoneySymbol = value;176             }177         }178 179         private decimal minimum = -99999999999M;180         /// <summary>181         /// 最小值182         /// </summary>183         [DefaultValue(typeof(decimal), "-99999999999")]184         [Description("最小值。")]185         [RefreshProperties(RefreshProperties.Repaint)]186         public decimal Minimum187         {188             get { return minimum; }189             set190             {191                 if (value >= maximum)192                     throw new ArgumentOutOfRangeException("最小值必须小于最大值。");193                 else194                     minimum = value;195             }196         }197 198         private decimal maximum = 99999999999M;199         /// <summary>200         /// 最大值201         /// </summary>202         [DefaultValue(typeof(decimal), "99999999999")]203         [Description("最大值。")]204         [RefreshProperties(RefreshProperties.Repaint)]205         public decimal Maximum206         {207             get { return maximum; }208             set209             {210                 if (value <= minimum)211                     throw new ArgumentOutOfRangeException("最大值必须大于最小值。");212                 else213                     maximum = value;214             }215         }216 217         private HorizontalAlignment editTextAlign = HorizontalAlignment.Left;218         /// <summary>219         /// 指示编辑时文本在编辑框中的对齐方式220         /// </summary>221         [DefaultValue(HorizontalAlignment.Left)]222         [Description("指示编辑时文本在编辑框中的对齐方式。")]223         [RefreshProperties(RefreshProperties.Repaint)]224         public HorizontalAlignment EditTextAlign225         {226             get { return editTextAlign; }227             set { editTextAlign = value; }228         }229 230         /// <summary>231         /// 单元格模板232         /// </summary>233         public override DataGridViewCell CellTemplate234         {235             get236             {237                 return base.CellTemplate;238             }239             set240             {241                 if (value =http://www.mamicode.com/= null || (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewNumericCell))))242                     throw new ArgumentException("单元格模板类型不是FinanceCell或其子类。");243                 else244                     base.CellTemplate = value;245             }246         }247 248         #endregion Fields and properties249 250         /// <summary>251         /// 数值列252         /// </summary>253         public DataGridViewNumericColumn()254             : base()255         {256             this.CellTemplate = new DataGridViewNumericCell();257         }258 259         /// <summary>260         /// 重写克隆方法261         /// </summary>262         /// <returns></returns>263         public override object Clone()264         {265             DataGridViewNumericColumn column = (DataGridViewNumericColumn)base.Clone();266             column.CellTemplate = new DataGridViewNumericCell();267             column.DecimalPlaceColor = this.DecimalPlaceColor;268             column.LineSpace = this.LineSpace;269             column.MoneySymbol = this.MoneySymbol;270             column.NegativeShowRed = this.NegativeShowRed;271             column.NormalColor = this.NormalColor;272             column.Scale = this.Scale;273             column.ShowMoneySymbol = this.ShowMoneySymbol;274             column.ShowLine = this.ShowLine;275             column.ThousandsSeparatorColor = this.ThousandsSeparatorColor;276             column.EditTextAlign = this.EditTextAlign;277             return column;278         }279 280     }281 282 }

 

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

技术分享

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

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

 

相关文章

  • 用Label控件模拟网页链接 
  • DataGridView列标题可编辑组件
  • 多列下拉框和鼠标相关组件

.NET组件控件实例编程系列——5.DataGridView数值列和日期列