本文转自:大气象学习园地
http://greatverve.cnblogs.com/archive/2012/06/14/DataGridView-CellValidating.html

感谢原文作者!
 

如果是TextBox可以通过KeyPress()事件,让用户无法输入非法数据。DataGridView中的单元格,无法通过KeyPress()控制,可能我没找到方法。通过CellValidating()在用户结束编辑时判断,如果不合法则还原数据。


 
 
          
  1. private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 
  2. //可编辑的列 
  3. if (e.ColumnIndex != 2 && e.ColumnIndex != 3) 
  4. return
  5. double outDb = 0; 
  6. if (double.TryParse(e.FormattedValue.ToString(), out outDb)) 
  7. {
  8. e.Cancel = false
  9. else 
  10. e.Cancel = true;//数据格式不正确则还原 
  11. dataGridView1.CancelEdit(); 
 
TextBox的KeyPress()事件
 
 
 
          
  1. private void txtK_KeyPress(object sender, KeyPressEventArgs e) 
  2.       double outDb = 0; 
  3.      if (double.TryParse(txtK.Text + e.KeyChar.ToString(), out outDb)) 
  4.      { 
  5.          e.Handled = false
  6.      } 
  7.      else 
  8.      { 
  9.          e.Handled = true
  10.      } 
 
我继承TextBox重写KeyPress()封装了个自定义控件。
url: http://greatverve.cnblogs.com/archive/2012/06/14/DataGridView-CellValidating.html
定义单元格验证
要求:
    验证错误后焦点不离开。
实现:
    单元格的验证可以使用dgv_details_CellValidating事件。验证不通过时调用e.Cancel = true;终止事件链,单元格将保持编辑状态。调用dgv_details.CancelEdit();可以使单元格的内容会滚到修改前的值。使用System.Windows.Forms.SendKeys.Send("^a");将全选单元格的内容。

    单元格选中并开始编辑状态
实现:
     //DataGridView获得焦点
     dgv_details.Focus();
     //DataGridView指定当前单元格
    dgv_details.CurrentCell = dgv_details[0, 0];
    //开始编辑状态
    dgv_details.BeginEdit(false);

    定制自动生成绑定了列
实现:
    dgv_details.AutoGenerateColumns = false;

   设置列的背景色
实现:
      Color GridReadOnlyColor = Color.LightGoldenrodYellow;
     dgv_details.Columns[1].DefaultCellStyle.BackColor =WinKeys.GridReadOnlyColor;

DataGridView单元格验证的设计的问题
     问题一:绑定还是不绑定?
绑定的优势:比较简单,代码少。
绑定得缺点:DataGridView中的数据受数据源的影响(主键约束、值类型约束)。不一至时会激发DataError事件,输入的内容无法保存到单元格中和数据源中。特殊的验证(比如长度、格式等)还是需要另外写代码实现。关于增加行的问题。增加新行时多主键的验证有问题,而且验证不通过时会将新行全部删除。限制很多,很不方便。

非绑定的优势:验证等处理比较灵活。不受数据源的约束。
非绑定得缺点:显示和向数据库更新数据时需要比较多的代码实现,效率比较低。

总的感觉在处理验证比较麻烦的场合,我还是比较喜欢非绑定的方式。如果数据量大,验证比较简单的场合使用绑定模式比较好。

 自己项目中写的一个,以备留存参考:

 

 
  
  1. //单元格验证事件//检查XX是否存在重复 
  2.        private void dgvCode_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 
  3.        { 
  4.            if (e.ColumnIndex == 0) 
  5.            { 
  6.                for (int i = 0; i < dgvCode.Rows.Count; i++) 
  7.                { 
  8.                    //排除当前单元格,单元格为空字符串是不检测 
  9.                    if (e.RowIndex == i || String.IsNullOrEmpty(dgvCode[0, i].Value.ToString())) 
  10.                    { 
  11.                        continue
  12.                    } 
  13.                     
  14.                    if (e.FormattedValue.ToString().Equals(dgvCode[0, i].Value.ToString())) 
  15.                    { 
  16.                        MessageBox.Show("XX已存在,请修改!""提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 
  17.                        e.Cancel = true
  18.                        dgvCode.CancelEdit(); 
  19.                        return
  20.                    } 
  21.                } 
  22.            } 
  23.        }