在使用DataGridView編輯數據的時候,編輯的單元格通常會顯示爲文本框,邏輯值和圖片會自動顯示對應類型的列。固然咱們本身能夠手工選擇列的類型,例如ComboBox列、Button列、Link列。在編輯數值和日期類型的時候,若是使用獨立控件,咱們會選擇NumericUpDown和DataTimePicker,但在DataGridView中編輯的時候就只能用文本列。相比使用獨立控件,文本框列缺乏數值有效性檢測,數值區間限制等功能。從本質上來看,.NET自己提供的DataGridViewCheckBoxColumn、DataGridViewComboBoxColumn之類的列,內部是集成了CheckBox和ComboBox。咱們本身也能夠實現相似的表格列,將獨立控件添加到其中。本文就介紹如何將數值控件NumericUpDown和日期控件DateTimePicker添加到表格列中,實現自定義表格列。先上圖,看看實現以後的效果:html
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 }
(2)定義單元格,繼承自DataGridViewTextBoxCell。在其中定義EditType爲上一步定義的CalendarEditingControl,並設置ValueType爲DateTime。因爲在使用過程當中是給列控件設置屬性,例如容許設置的日期最大最小值,而實際日期限制須要修改上一步定義的編輯控件的值。因此須要在初始化編輯控件的方法中獲取列的屬性並給編輯控件賦值。git
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 }
(3)定義日期列,繼承自DataGridViewColumn。在構造函數中設置單元格模板爲上一步定義的DataGridViewCalendarCell,實際編輯時就會顯示爲日期單元格。能夠根據須要添加屬性,例如用CustomFormat自定義日期顯示格式,用MinDate、MaxDate限制日期範圍。express
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 }
二、NumericColumn(數值列)原文地址:http://www.cnblogs.com/conexpress/p/5923324.htmlide
(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, 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 }
(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 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
(3)定義列,繼承自DataGridViewColumn。因爲要支持會計帳簿的數值顯示效果,添加了不少控制顯示效果的屬性。this
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添加列的時候,下拉選擇列的類型,就能夠看到自定義的列了。spa
在實現自定義列的過程當中能夠根據須要添加相關的控制屬性,例如限制輸入值的範圍、顯示效果控制等。在理解實現自定義列的方法以後,就能夠實現更多個性化的列。code
代碼下載地址:http://files.cnblogs.com/files/conexpress/DataGridViewColumns.zipcomponent
相關文章