DataGridView数值列和日期列

时间:2022-09-26 11:56:21

本文转自:http://www.cnblogs.com/conexpress/p/5923324.html

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

日期列:可自定义显示格式,编辑的时候会显示DateTimePicker控件。
DataGridView数值列和日期列
 
数值列:可选择显示财务账簿中的金额格式,编辑的时候显示NumericUpDown控件。
DataGridView数值列和日期列
实现自定义表格列步骤如下:
1、定义要单元格编辑控件类,该类继承自要嵌入单元格的独立控件,并实现接口IDataGridViewEditingControl
2、定义单元格,继承自DataGridViewTextBoxCell,重写属性EditType(返回上一步定义的控件类型)、ValueType(返回要编辑值的类型)、DefaultNewRowValue(返回要编辑值的默认值)以及方法InitializeEditingControl(获取上一步定义的单元格编辑控件的实例,并设置实例相关属性)
3、定义表格列,继承自DataGridViewColumn,定义要设置的属性,在构造函数中设置CellTemplate属性为上一步定义的单元格的实例。重写属性CellTemplate,在set中检测value的类型必须是上一步定义的单元格类型。重写Clone方法,在其中创建当前类型的新实例,将base.Clone()获取的列实例的属性一一赋值给新实例。
 
下面是实际的代码
1、CalendarColumn(日期列)
(1)首先定义日期编辑控件,即用来编辑单元格中数值的控件。需要继承自日期控件DateTimePicker并实现IDataGridViewEditingControl接口。
DataGridView数值列和日期列
 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, IDataGridViewEditingControl
11 {
12 public CalendarEditingControl()
13 : base()
14 { }
15
16 #region IDataGridViewEditingControl Members
17
18 public object EditingControlFormattedValue
19 {
20 get { return Value.ToLongDateString(); }
21 set
22 {
23 var newValue = value as String;
24 if (newValue != null)
25 {
26 Value = 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 RepositionEditingControlOnValueChange
68 {
69 get { return false; }
70 }
71
72 public DataGridView EditingControlDataGridView { get; set; }
73
74 public bool EditingControlValueChanged { get; set; }
75
76 public Cursor EditingPanelCursor
77 {
78 get { return base.Cursor; }
79 }
80
81 #endregion
82
83 protected override void OnValueChanged(EventArgs eventargs)
84 {
85 this.EditingControlValueChanged = true;
86 EditingControlDataGridView.NotifyCurrentCellDirty(true);
87 base.OnValueChanged(eventargs);
88 }
89
90 }
91 }
DataGridView数值列和日期列

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

DataGridView数值列和日期列
 1 using System;
2 using System.Windows.Forms;
3
4 namespace CodeLibrary.Controls.DataGridViewColumns
5 {
6 /// <summary>
7 /// 日期单元格
8 /// </summary>
9 public class DataGridViewCalendarCell : DataGridViewTextBoxCell
10 {
11 /// <summary>
12 /// 构造函数
13 /// </summary>
14 public DataGridViewCalendarCell()
15 : base()
16 {
17 }
18
19 /// <summary>
20 /// 编辑控件的类型
21 /// </summary>
22 public override Type EditType
23 {
24 get { return typeof(CalendarEditingControl); }
25 }
26
27 /// <summary>
28 /// 值类型
29 /// </summary>
30 public override Type ValueType
31 {
32 get { return typeof(DateTime); }
33 }
34
35 /// <summary>
36 /// 默认新值
37 /// </summary>
38 public override object DefaultNewRowValue
39 {
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 }
DataGridView数值列和日期列

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

DataGridView数值列和日期列
  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 }
DataGridView数值列和日期列

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

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

DataGridView数值列和日期列
 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, IDataGridViewEditingControl
10 {
11 #region Implementation of IDataGridViewEditingControl
12
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 EditingControlDataGridView
50 { get; set; }
51
52 public object EditingControlFormattedValue
53 {
54 get { return Value.ToString(); }
55 set { Value = decimal.Parse(value.ToString()); }
56 }
57
58 public int EditingControlRowIndex { get; set; }
59
60 public bool EditingControlValueChanged
61 {
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 IDataGridViewEditingControl
71
72 protected override void OnValueChanged(EventArgs eventargs)
73 {
74 editingControlValueChanged = true;
75 EditingControlDataGridView.NotifyCurrentCellDirty(true);
76 base.OnValueChanged(eventargs);
77 }
78
79 }
80
81 }
DataGridView数值列和日期列

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

DataGridView数值列和日期列
  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 else
104 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 else
150 {
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 else
188 {
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 else
244 {
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 else
251 {
252 using (Pen normalPen = new Pen(NormalColor, 1.0F))//绘制普通线
253 graphics.DrawLine(normalPen, PointStart, PointEnd);
254 }
255 }
256 }
257 else
258 {
259 left = 0;
260 }
261 digitIndex++;
262 }
263 }
264
265 #endregion 自定义绘制
266
267 /// <summary>
268 /// 编辑类型
269 /// </summary>
270 public override Type EditType
271 {
272 get { return typeof(NumericUpDownEditingControl); }
273 }
274
275 /// <summary>
276 /// 值类型
277 /// </summary>
278 public override Type ValueType
279 {
280 get { return typeof(decimal); }
281 }
282
283 /// <summary>
284 /// 默认值
285 /// </summary>
286 public override object DefaultNewRowValue
287 {
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 = Convert.ToDecimal(this.Value);
310 }
311 }
312
313 }//class FinanceTextBoxCell
314
315 }//namespace
DataGridView数值列和日期列

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

DataGridView数值列和日期列
  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 NormalColor
104 {
105 get { return normalColor; }
106 set
107 {
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 Scale
121 {
122 get { return scale; }
123 set
124 {
125 if (value < 0)
126 throw new ArgumentOutOfRangeException("小数位数不允许小于零。");
127 else
128 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 NegativeShowRed
140 {
141 get { return negativeShowRed; }
142 set
143 {
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 MoneySymbol
157 {
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 ShowMoneySymbol
170 {
171 get { return showMoneySymbol; }
172 set
173 {
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 Minimum
187 {
188 get { return minimum; }
189 set
190 {
191 if (value >= maximum)
192 throw new ArgumentOutOfRangeException("最小值必须小于最大值。");
193 else
194 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 Maximum
206 {
207 get { return maximum; }
208 set
209 {
210 if (value <= minimum)
211 throw new ArgumentOutOfRangeException("最大值必须大于最小值。");
212 else
213 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 EditTextAlign
225 {
226 get { return editTextAlign; }
227 set { editTextAlign = value; }
228 }
229
230 /// <summary>
231 /// 单元格模板
232 /// </summary>
233 public override DataGridViewCell CellTemplate
234 {
235 get
236 {
237 return base.CellTemplate;
238 }
239 set
240 {
241 if (value == null || (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewNumericCell))))
242 throw new ArgumentException("单元格模板类型不是FinanceCell或其子类。");
243 else
244 base.CellTemplate = value;
245 }
246 }
247
248 #endregion Fields and properties
249
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数值列和日期列

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

DataGridView数值列和日期列

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

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

DataGridView数值列和日期列的更多相关文章

  1. 在论坛中出现的比较难的sql问题:39&lpar;动态行转列 动态日期列问题&rpar;

    原文:在论坛中出现的比较难的sql问题:39(动态行转列 动态日期列问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉 ...

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

    在使用DataGridView编辑数据的时候,编辑的单元格一般会显示为文本框,逻辑值和图片会自动显示对应类型的列.当然我们自己可以手工选择列的类型,例如ComboBox列.Button列.Link列. ...

  3. datagridview 日期列排序

    1.datagridview 日期列排序 private void Form1_Load(object sender, EventArgs e) { //方法1 dataGridView1.Colum ...

  4. 怎么自定义DataGridViewColumn(日期列,C&num;&rpar;

    参考:https://msdn.microsoft.com/en-us/library/7tas5c80.aspx 未解决的问题:如果日期要设置为null,怎么办? DataGridView控件提供了 ...

  5. easyUI的datagrid控件日期列不能正确显示Json格式数据的解决方案

    EasyUI是一套比较轻巧易用的Jquery控件,在使用过程中遇到一个问题,它的列表控件——datagrid, 在显示日期列的时候,由于后台返回给页面的数据是Json格式的,其中的日期字段,在后台是正 ...

  6. 实现DataGridView控件中CheckBox列的使用

    最近做WindowsForms程序,使用DataGridView控件时,加了一列做选择用,发现CheckBox不能选中.搜索后,要实现DataGridView的CellContentClick事件,将 ...

  7. easyUI的datagrid控件日期列格式化

    转自:https://blog.csdn.net/idoiknow/article/details/8136093 EasyUI是一套比较轻巧易用的Jquery控件,在使用过程中遇到一个问题,它的列表 ...

  8. &lbrace; MySQL基础数据类型&rcub;一 介绍 二 数值类型 三 日期类型 四 字符串类型 五 枚举类型与集合类型

    MySQL基础数据类型 阅读目录 一 介绍 二 数值类型 三 日期类型 四 字符串类型 五 枚举类型与集合类型 一 介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己 ...

  9. java 散列与散列码探讨 &comma;简单HashMap实现散列映射表运行各种操作示列

    java 散列与散列码探讨 ,简单HashMap实现散列映射表运行各种操作示列 package org.rui.collection2.maps; /** * 散列与散列码 * 将土拔鼠对象与预报对象 ...

随机推荐

  1. quick-cocos2d-x 实现在lua里面完成android支付宝的接入

    quick-cocos2d-x 实现在lua里面完成android支付宝的接入 一.支付宝注册是很麻烦的一个过程,本文就不解释了,想了解的去官网看下注册流程.然后下载他们的sdk-WS_SECURE_ ...

  2. 做webapp静态页面的一些积累

    ​1)根据pad,手机不同的版本的屏幕大小设置字体的大小(可以使用此方式根据屏幕的不同进行设置,由于我左边的图片是设置的float='left',使用的是img标签的百分比来显示图片) (使用此方式, ...

  3. &lbrack;leetcode 48&rsqb; rotate image

    1 题目 You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwi ...

  4. iOS开发Swift篇—(三)字符串和数据类型

    iOS开发Swift篇—(三)字符串和数据类型 一.字符串 字符串是String类型的数据,用双引号""包住文字内容  let website = "http://www ...

  5. Android ExpandableListView实例Demo

    前几篇文章介绍了Listview.但在实际开发中也常常会用到多层的Listview来展示数据,比方qq中的好友展示,所以这张来了解一下ExpandableListview.基本思想与Listview大 ...

  6. CSS 特效 &lpar;教程还是英文的好&rpar;

    Border-radius: create rounded corners with CSS! http://www.css3.info/preview/rounded-border/

  7. Python函数参数的五种类型

    之前项目需求,需要通过反射获取函数的参数,python中可以通过函数签名(signature)来实现. 首先需要了解函数参数的类型,Python的参数类型一共有5种:POSITIONAL_OR_KEY ...

  8. GTK图形控件中的rc文件使用心得

    转载自: 1.http://blog.csdn.net/saintwinona/article/details/6972754 2. (1).GTK 主题指南 1.Widgets         GT ...

  9. InfluxDB配置文件详解

    全局配置 # 该选项用于上报influxdb的使用信息给InfluxData公司,默认值为false reporting-disabled = false # 备份恢复时使用,默认值为8088 bin ...

  10. &lbrack;UI&rsqb; 精美UI界面欣赏&lbrack;5&rsqb;

    精美UI界面欣赏[5]