一.引子
當我們在做WinForm的數據庫開發時,時常會用到datagridvIEw控件來顯示數據.在提供數據交互的時候,常常希望可以對用戶輸入的數據進行校驗.對於一些類似金額的字段,要求只允許輸入數字,並且要控制精度.這個時候,我們通常會想到2種解決方法.其一,就是先任隨用戶輸入,然後在Invalidating或lostfocus等事件中做驗證並提示.其二,就是我這裡所演示的方法,就是直接控制用戶的輸入,這樣將省略去很多冗繁的操作,給數據庫程序的快速開發帶來方便.
二.設計時效果
三.運行時效果
四.源代碼
1)DataGridVIEwTextBoxCell
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
namespace JcsExpLibary.Numeric_Textbox
...{
public class JcsNumTextBoxCell : DataGridVIEwTextBoxCell
...{
private bool _isreadonly = true; //是否允許回車代替TAB
private bool _isintegral = false;//是否整數輸入
private bool _EnPaste = true;//是否允許粘貼
private bool _EnContextMenu = true; //是否允許現實右鍵菜單
private int _PointNumber = -1;//為-1時允許輸入任意位小數
private bool _isnegativenumber = false; //是否允許輸入負數
public JcsNumTextBoxCell(): base()
...{
}
/**//// <summary>
/// 是否只讀
/// </summary>
[Category("JCS屬性"), Description("是否只讀。")]
public bool Isreadonly
...{
get ...{ return this._isreadonly; }
set ...{ this._isreadonly = value; }
}
/**//// <summary>
/// 是否是整數
/// </summary>
[Category("JCS屬性"), Description("是否整數。")]
public bool isintegral
...{
get ...{ return this._isintegral; }
set ...{ _isintegral = value; }
}
/**//// <summary>
/// 是否允許輸入負數
/// </summary>
[Category("JCS屬性"), Description("是否允許輸入負數。")]
public bool IsNegativeNumber
...{
[Category("JCS屬性"), Description("是否整數。")]
public bool isintegral
...{
get ...{ return this._isintegral; }
set ...{ _isintegral = value; }
}
/**//// <summary>
/// 是否允許輸入負數
/// </summary>
[Category("JCS屬性"), Description("是否允許輸入負數。")]
public bool IsNegativeNumber
...{
get ...{ return _isnegativenumber; }
set ...{ _isnegativenumber = value; }
}
/**//// <summary>
/// 精度位數控制(即:允許輸入幾位小數控制)
/// </summary>
[Category("JCS屬性"), Description("精度位數控制,-1時允許輸入任意位小數。")]
public int PointNumber
...{
get ...{ return _PointNumber; }
set ...{ this._PointNumber = value; }
}
[Category("JCS屬性"), Description("是否允許粘貼。")]
public bool EnablePaste
...{
get ...{ return _EnPaste; }
set
...{
_EnPaste = value;
}
}
/**//// <summary>
///
/// </summary>
[Category("JCS屬性"), Description("是否右鍵菜單。")]
public bool EnableContextMenu
...{
get ...{ return _EnContextMenu; }
set
...{
_EnContextMenu = value;
}
}
//初始化用於編輯單元格的控件
public override void InitializeEditingControl(int rowIndex,
object initialFormattedValue,
DataGridViewCellStyle dataGridVIEwCellStyle)
...{
JcsNumTextBoxEditingControl numbertextbox;
JcsNumTextBoxColumn jcsnumcol;
DataGridVIEwColumn dgvc;
base.InitializeEditingControl(rowIndex, initialFormattedValue,
dataGridVIEwCellStyle);
//獲取承載控件
numbertextbox = DataGridVIEw.EditingControl as JcsNumTextBoxEditingControl;
//獲取包含此單元格的列
dgvc = this.OwningColumn; // this.DataGridVIEw.Columns[this.ColumnIndex];
if (dgvc is JcsNumTextBoxColumn)
...{
jcsnumcol = dgvc as JcsNumTextBoxColumn;
numbertextbox.Isreadonly = jcsnumcol.Isreadonly;
numbertextbox.isintegral = jcsnumcol.isintegral;
numbertextbox.IsNegativeNumber = jcsnumcol.IsNegativeNumber;
numbertextbox.PointNumber = jcsnumcol.PointNumber;
numbertextbox.EnablePaste = jcsnumcol.EnablePaste;
numbertextbox.EnableContextMenu = jcsnumcol.EnableContextMenu;
numbertextbox.Text = (string)this.Value;
}
}
//獲取單元格的寄宿編輯控件的類型
public override Type EditType
...{
get
...{
return typeof(JcsNumTextBoxEditingControl);
}
}
}
}
2)DataGridVIEwColumn
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
namespace JcsExpLibary.Numeric_Textbox
...{
public class JcsNumTextBoxColumn : DataGridVIEwColumn
...{
private bool _isreadonly = true; //是否允許回車代替TAB
private bool _isintegral = false;//是否整數輸入
private bool _EnPaste = true;//是否允許粘貼
private bool _EnContextMenu = true; //是否允許現實右鍵菜單
private int _PointNumber = -1;//為-1時允許輸入任意位小數
private bool _isnegativenumber = false; //是否允許輸入負數
public JcsNumTextBoxColumn()
: base(new JcsNumTextBoxCell())
...{
}
/**//// <summary>
/// 是否只讀
/// </summary>
[Category("JCS屬性"), Description("是否只讀。")]
public bool Isreadonly
...{
get ...{ return this._isreadonly; }
set ...{ this._isreadonly = value; }
}
/**//// <summary>
/// 是否是整數
/// </summary>
[Category("JCS屬性"), Description("是否整數。")]
public bool isintegral
...{
get ...{ return this._isintegral; }
set
...{
if (this._isintegral != value)
...{
this._isintegral = value;
JcsNumTextBoxCell jcsnumcel;
DataGridVIEwCell dgvc;
int rowCount;
//
// first, update the value on the template cell.
//
jcsnumcel = (JcsNumTextBoxCell)this.CellTemplate;
jcsnumcel.isintegral = value;
//
// now set it on all cells in other rows as well.
//
if (this.DataGridView != null && this.DataGridVIEw.Rows != null)
...{
rowCount = this.DataGridVIEw.Rows.Count;
for (int i = 0; i < rowCount; i++)
...{
dgvc = this.DataGridVIEw.Rows.SharedRow(i).Cells[i];
if (dgvc is JcsNumTextBoxCell)
...{
jcsnumcel = (JcsNumTextBoxCell)dgvc;
jcsnumcel.isintegral = value;
}
}
}
}
}
}
/**////&;<summary>
/// 是否允許輸入負數
/// </summary>
[Category("JCS屬性"), Description("是否允許輸入負數。")]
public bool IsNegativeNumber
...{
get ...{ return _isnegativenumber; }
set ...{ _isnegativenumber = value; }
}
/**//// <summary>
/// 精度位數控制(即:允許輸入幾位小數控制)
/// </summary>
[Category("JCS屬性"), Description("精度位數控制,-1時允許輸入任意位小數。")]
public int PointNumber
...{
get ...{ return _PointNumber; }
set ...{ this._PointNumber = value; }
}
[Category("JCS屬性"), Description("是否允許粘貼。")]
public bool EnablePaste
...{
get ...{ return _EnPaste; }
set
...{
_EnPaste = value;
}
/**//// <summary>
///
/// </summary>
[Category("JCS屬性"), Description("是否右鍵菜單。")]
public bool EnableContextMenu
...{
get ...{ return _EnContextMenu; }
set
...{
_EnContextMenu = value;
}
}
//獲取或設置用於創建新單元格的模板
public override DataGridVIEwCell CellTemplate
...{
get
...{
return base.CellTemplate;
}
set
...{
//
if (value != null && !value.GetType().IsAssignableFrom(typeof(JcsNumTextBoxCell)))
...{
string s = "Cell type is not based upon the JcsNumTextBoxCell.";
throw new InvalidCastException(s);
}
base.CellTemplate = value;
}
}
}
}
3)JcsNumTextBoxEditingControl
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace JcsExpLibary.Numeric_Textbox
...{
public class JcsNumTextBoxEditingControl:JcsInputNum ,IDataGridVIEwEditingControl
...{
protected int rowIndex;
protected DataGridView dataGridVIEw;
protected bool valueChanged = false;
public JcsNumTextBoxEditingControl()
...{
}
//重寫jcsinputnum的ontextchanged
protected override void OnTextChanged(EventArgs e)
...{
base.OnTextChanged(e);
//通知datagridvIEw值已經更改
NotifyDataGridVIEwOfValueChange();
}
//通知DataGridVIEw值已經更改
protected virtual void NotifyDataGridVIEwOfValueChange()
...{
this.valueChanged = true;
if (this.dataGridVIEw != null)
...{
//設置當前單元格有未提交的更改
this.dataGridVIEw.NotifyCurrentCellDirty(true);
}
}
IDataGridViewEditingControl Members#region IDataGridVIEwEditingControl Members
//獲取當鼠標指針位於 DataGridVIEw.EditingPanel 上方但不位於編輯控件上方時所使用的光標
public Cursor EditingPanelCursor
...{
get
...{
return Cursors.IBeam;
}
}
//獲取或設置所在的DataGridVIEw.
public DataGridView EditingControlDataGridVIEw
...{
get
...{
return this.dataGridVIEw;
&nb }
set
...{
this.dataGridVIEw = value;
}
}
//獲取或設置value(按照指定format)
public object EditingControlFormattedValue
...{
set
...{
this.Text = value.ToString();
NotifyDataGridVIEwOfValueChange();
}
get
&nb ...{
return this.Text;
}
}
//檢索單元格的格式化值
public object GetEditingControlFormattedValue(DataGridVIEwDataErrorContexts context)
...{
return this.Text;
}
//確定指定的鍵是應由編輯控件處理的常規輸入鍵,還是應由 DataGridVIEw 處理的特殊鍵
public bool EditingControlWantsInputKey(Keys keyData, bool dataGridVIEwWantsInputKey)
...{
switch (keyData & Keys.KeyCode)
...{
case Keys.Right:
//
if (!(this.SelectionLength == 0
&& this.Selection== this.ToString().Length))
...{
return true;
}
break;
case Keys.Left:
//
if (!(this.SelectionLength == 0
&& this.SelectionStart == 0))
...{
return true;
}
break;
case Keys.Home:
case Keys.End:
if (this.SelectionLength != this.ToString().Length)
...{
return true;
}
break;
case Keys.Prior:
case Keys.Next:
if (this.valueChanged)
...{
return true;
}
break;
case Keys.Delete:
if (this.SelectionLength > 0 || this.SelectionStart < this.ToString().Length)
...{
return true;
}
break;
}
//
return !dataGridVIEwWantsInputKey;
}
//准備接受修改
public void PrepareEditingControlForEdit(bool selectAll)
...{
if (selectAll)
...{
SelectAll();
}
else
...{
//光標設置於末尾
this.SelectionStart = this.ToString().Length;
}
}
//獲取或設置一個值,該值指示每當值更改時,是否需要重新定位單元格的內容
public bool RepositionEditingControlOnValueChange
...{
get
...{
return false;
}
}
//獲取或設置該承載單元格的父行的索引
public int EditingControlRowIndex
...{
get
...{
return this.rowIndex;
}
set
...{
this.rowIndex = value;
}
}
//更改控件的用戶界面 (UI),使之與指定單元格樣式一致
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridVIEwCellStyle)
...{
this.Font = dataGridVIEwCellStyle.Font;
this.ForeColor = dataGridVIEwCellStyle.ForeColor;
this.BackColor = dataGridVIEwCellStyle.BackColor;
this.TextAlign = translateAlignment(dataGridVIEwCellStyle.Alignment);
}
//獲取或設置一個值,該值指示編輯控件的值是否與承載單元格的值不同
public bool EditingControlValueChanged
...{
get
...{
return valueChanged;
}
set
...{
this.valueChanged = value;
}
}
#endregion // IDataGridVIEwEditingControl.
/**//// Routine to translate between DataGridVIEw
/// content alignments and text box horizontal alignments.
private static HorizontalAlignment translateAlignment(DataGridVIEwContentAlignment align)
...{
switch (align)
...{
case DataGridVIEwContentAlignment.TopLeft:
case DataGridVIEwContentAlignment.MiddleLeft:
case DataGridVIEwContentAlignment.BottomLeft:
return HorizontalAlignment.Left;
case DataGridVIEwContentAlignment.TopCenter:
case DataGridVIEwContentAlignment.MiddleCenter:
case DataGridVIEwContentAlignment.BottomCenter:
return HorizontalAlignment.Center;
case DataGridVIEwContentAlignment.TopRight:
case DataGridVIEwContentAlignment.MiddleRight:
case DataGridVIEwContentAlignment.BottomRight:
return HorizontalAlignment.Right;
}
throw new ArgumentException("Error: Invalid Content Alignment!");
}
}
}
4)測試代碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using JcsExpLibary.Numeric_Textbox;
namespace WindowsApplication1
...{
public partial class Form9 : Form
...{
public Form9()
...{
InitializeComponent();
InitializeDataGridVIEwColumns();
}
private void InitializeDataGridVIEwColumns()
...{
DataGridVIEwTextBoxColumn dgvtbc;
JcsNumTextBoxColumn jcsnumtextcol;
//
// employee name.
//
dgvtbc = new DataGridVIEwTextBoxColumn();
dgvtbc.HeaderText = "Name";
&nb dgvtbc.Width = 120;
this.dataGridVIEw1.Columns.Add(dgvtbc);
//
// Employee Value
//
jcsnumtextcol = new JcsNumTextBoxColumn();
jcsnumtextcol.HeaderText = "Employee Value";
jcsnumtextcol.isintegral = false;
jcsnumtextcol.IsNegativeNumber = true;
jcsnumtextcol.PointNumber = 2;
jcsnumtextcol.EnableContextMenu = false;
jcsnumtextcol.EnablePaste = false;
jcsnumtextcol.Width = 75;
this.dataGridVIEw1.Columns.Add(jcsnumtextcol);
//
// Address
//
dgvtbc = new DataGridVIEwTextBoxColumn();
dgvtbc.HeaderText = "Address";
dgvtbc.Width = 150;
this.dataGridVIEw1.Columns.Add(dgvtbc);
//
// City
//
dgvtbc = new DataGridVIEwTextBoxColumn();
dgvtbc.HeaderText = "City";
dgvtbc.Width = 75;
this.dataGridVIEw1.Columns.Add(dgvtbc);
//
// Department Code
//
dgvtbc = new DataGridVIEwTextBoxColumn();
dgvtbc.HeaderText = "Department";
dgvtbc.ValueType = typeof(int);
dgvtbc.Width = 75;
this.dataGridVIEw1.Columns.Add(dgvtbc);
}
}
}