博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转载部分修改】C#如何在DataGridView控件中验证数据输入
阅读量:6370 次
发布时间:2019-06-23

本文共 13480 字,大约阅读时间需要 44 分钟。

原文链接:    

  实现控件中验证数据输入功能主要是利用DataGridView控件的公共事件CellValidatingCellEndEdit事件在为当前选定的单元格停止编辑模式时发生。本实例判断控件第一列中单元格的值是否为空。在事件中进行验证,如果严重失败,将System.Windows.Forms.DataGridViewCellValidatingEventArgs类的Cancel属性设置为True。这将导致DataGridView控件阻止光标离开该单元格。将该行的ErrorText属性设置为解释性字符串,将显示错误图标,其工具提示将保护此错误文本。在CellEndEdit事件处理程序中,将该行的ErrorText属性设置为空字符串。只有当单元格退出编辑模式(如果验证失败,则不能退出单元格)时,才能发生。运动程序,编辑控件的第一列,在单元格中不输入内容,然后使用鼠标单击其他单元格,这样就会提示错误!

下面给出主要代码:
 
Private void dataGridView1_CellValidating(object sender,DataGridViewCellValidatingEventArgs e) {   If (e.ColumnIndex==0)      {         If(String.IsNullOrEmpty(e.FormattedValue.ToString))         {           dataGridView1.Rows[e.RowIndex].ErrorText=”单元格第一列值不能为空”;           e.Cancel=true;         } int n = 0;                //先转化成int类型,尝试转化                if (int.TryParse(e.FormattedValue.ToString(), out n))                {                    //可以的话,再进一步范围判断                    if (n < 1 || n > 100)                    {                        dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "必须在1~100之内!";                    }                    else                    {                        dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "";                    }                }                else                {                    dataGridView1.Rows[e.RowIndex].ErrorText = "请输入数字";//转换失败,类型都有问题                    e.Cancel = true;                }     }}Private void dataGridView1_CellEndEdit(object sender,DataGridViewCellEventArgs e){      dataGridView1.Rows[e.RowIndex].ErrorText=String.Empty;}

原文链接:

把一个DataTable或者某个object集合的数据源绑定到DataGridView中,直接通过DataGridView数据录入需要进行额外的数据验证。数据验证总共分成两个大类:

I)类型验证:

所谓“类型验证”,就是输入的数据是不是可以(有效)转化成特定的类型(比如字段是int,但是输入确实abc等),这明显不符合要求。默认情况下,直接在绑定的DataGridView输入不符合类型的数据,当切换到下一条信息或者调用EndEdit方法将抛出异常。这很难看,我们可以通过处理DataError来实现强制性输入正确类型,代码非常简单:

[C#]

namespace WinFormCSharp{    public partial class Form1 : Form    {        DataTable dt = new DataTable();        DataGridView dv = new DataGridView();        public Form1()        {            InitializeComponent();            dt.Columns.Add("Id", typeof(int));            dt.Columns.Add("Name", typeof(string));        }        private void Form1_Load(object sender, EventArgs e)        {            for (int i = 1; i < 11; i++)            {                dt.Rows.Add(i, "Name" + i);            }            dt.AcceptChanges();            dv.Parent = this;            dv.Dock = DockStyle.Fill;            dv.DataSource = dt;            //自定义出错事件处理,到DataError这边处理            dv.DataError += new DataGridViewDataErrorEventHandler(dv_DataError);        }        void dv_DataError(object sender, DataGridViewDataErrorEventArgs e)        {            e.ThrowException = false;        }    }}

[VB.NET]

Namespace WinFormCSharp    Public Partial Class Form1        Inherits Form        Private dt As New DataTable()        Private dv As New DataGridView()        Public Sub New()            InitializeComponent()            dt.Columns.Add("Id", GetType(Integer))            dt.Columns.Add("Name", GetType(String))        End Sub        Private Sub Form1_Load(sender As Object, e As EventArgs)            For i As Integer = 1 To 10                dt.Rows.Add(i, "Name" & i)            Next            dt.AcceptChanges()            dv.Parent = Me            dv.Dock = DockStyle.Fill            dv.DataSource = dt            '自定义出错事件处理,到DataError这边处理            dv.DataError += New DataGridViewDataErrorEventHandler(AddressOf dv_DataError)        End Sub        Private Sub dv_DataError(sender As Object, e As DataGridViewDataErrorEventArgs)            e.ThrowException = False        End Sub    End ClassEnd Namespace

注意:DataError事件通常在调用EndEdit(DataGridView编辑完一行,开始下一行默认调用此事件)之后被触发,此时如果输入数据无法转换到列需要的那个类型就会触发DataError事件。因此你处理这个事件(通过把ThrowException=false)之后,异常框不会弹出,而是光标永久定格在那个单元格中(其余操作都无法做),直到你改变了数据符合规定的类型为止

II)自定义验证:

所谓“自定义验证”就是说录入数据在完全符合类型转换的条件下检查一些数据类型的范围。我们仍旧拿上面的举例子——假设规定Id范围只能在1~100之间,如何处理呢?

你可以处理CellValidating事件。该事件可以通过一个e.FormattedValue获取当前单元格内容,以便你对其进行操作。现在我们先假定排除第I种错误,纯粹是第二种,那么你应该在原来的基础上添加如下粗体部分的代码(Button是模拟保存数据到内存数据表中,顺便用于测试范围验证是否成功):

[C#]

namespace WinFormCSharp{    public partial class Form1 : Form    {        DataTable dt = new DataTable();        DataGridView dv = new DataGridView();        Button btn = new Button();           public Form1()        {            InitializeComponent();            dt.Columns.Add("Id", typeof(int));            dt.Columns.Add("Name", typeof(string));        }        private void Form1_Load(object sender, EventArgs e)        {            for (int i = 1; i < 11; i++)            {                dt.Rows.Add(i, "Name" + i);            }            dt.AcceptChanges();            dv.Parent = this;            dv.Dock = DockStyle.Fill;            dv.DataSource = dt;            //添加一个保存到DataTable中的按钮            btn.Parent = this;            btn.Dock = DockStyle.Bottom;            btn.Text = "Save To DataTable";            //当不满足条件,该字段为错误            dv.ShowCellErrors = true;            //处理单元格验证事件            dv.CellValidating += dv_CellValidating;            //处理按钮事件            btn.Click += new EventHandler(btn_Click);        }        void btn_Click(object sender, EventArgs e)        {                       bool flag=true; //默认没有错误            //循环遍历检测是否有错误            dv.Rows.Cast
().ToList().ForEach(row=>{ if(row.Cells[0].ErrorText!="") { flag=false; //有错误 } } ); if (flag) { dt.AcceptChanges(); } else { MessageBox.Show("注意,你的单元格中仍旧有错误!"); } } void dv_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) { //如果是第一个字段 if (e.ColumnIndex == 0) { //先转化成int类型 int n = int.Parse(e.FormattedValue.ToString()); //范围判断 if (n < 1 || n > 100) { dv.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "必须在1~100之内!"; } else { dv.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = ""; } } } void dv_DataError(object sender, DataGridViewDataErrorEventArgs e) { e.ThrowException = false; } }}

[VB.NET]

Namespace WinFormCSharp    Public Partial Class Form1        Inherits Form        Private dt As New DataTable()        Private dv As New DataGridView()        Private btn As New Button()        Public Sub New()            InitializeComponent()            dt.Columns.Add("Id", GetType(Integer))            dt.Columns.Add("Name", GetType(String))        End Sub        Private Sub Form1_Load(sender As Object, e As EventArgs)            For i As Integer = 1 To 10                dt.Rows.Add(i, "Name" & i)            Next            dt.AcceptChanges()            dv.Parent = Me            dv.Dock = DockStyle.Fill            dv.DataSource = dt            '添加一个保存到DataTable中的按钮            btn.Parent = Me            btn.Dock = DockStyle.Bottom            btn.Text = "Save To DataTable"            '当不满足条件,该字段为错误            dv.ShowCellErrors = True            '处理单元格验证事件            AddHandler dv.CellValidating, AddressOf dv_CellValidating            '处理按钮事件            AddHandler btn.Click, AddressOf btn_Click        End Sub        Private Sub btn_Click(sender As Object, e As EventArgs)            Dim flag As Boolean = True            '默认没有错误            '循环遍历检测是否有错误            dv.Rows.Cast(Of DataGridViewRow)().ToList().ForEach(Function(row)             If row.Cells(0).ErrorText <> "" Then                    '有错误                flag = False            End IfEnd Function)            If flag Then                dt.AcceptChanges()            Else                MessageBox.Show("注意,你的单元格中仍旧有错误!")            End If        End Sub        Private Sub dv_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs)            '如果是第一个字段            If e.ColumnIndex = 0 Then                '先转化成int类型                Dim n As Integer = Integer.Parse(e.FormattedValue.ToString())                '范围判断                If n < 1 OrElse n > 100 Then                    dv.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = "必须在1~100之内!"                Else                    dv.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = ""                End If            End If        End Sub        Private Sub dv_DataError(sender As Object, e As DataGridViewDataErrorEventArgs)            e.ThrowException = False        End Sub    End ClassEnd Namespace

由于DataGridView似乎没有公共的方法或属性直接判断有没有错误的单元格,所以按钮事件用扩展方法循环遍历每个行的第一列字段。

这样,类型和有效性验证都做到了!

不过我们可以精简代码(只用CellValidating事件一次性完成,因为该事件优先于DataError发生),通过设置其Cancel属性可以控制该事件是否被取消(“取消”会让光标定格在本单元格内,无法处理其它事情)。

[C#]

namespace WinFormCSharp{    public partial class Form1 : Form    {        DataTable dt = new DataTable();        DataGridView dv = new DataGridView();        Button btn = new Button();           public Form1()        {            InitializeComponent();            dt.Columns.Add("Id", typeof(int));            dt.Columns.Add("Name", typeof(string));        }        private void Form1_Load(object sender, EventArgs e)        {            for (int i = 1; i < 11; i++)            {                dt.Rows.Add(i, "Name" + i);            }            dt.AcceptChanges();            dv.Parent = this;            dv.Dock = DockStyle.Fill;            dv.DataSource = dt;            //添加一个保存到DataTable中的按钮            btn.Parent = this;            btn.Dock = DockStyle.Bottom;            btn.Text = "Save To DataTable";            //当不满足条件,该字段为错误            dv.ShowCellErrors = true;            //处理单元格验证事件            dv.CellValidating += dv_CellValidating;        }        void btn_Click(object sender, EventArgs e)        {                       bool flag=true; //默认没有错误            //循环遍历检测是否有错误            dv.Rows.Cast
().ToList().ForEach(row=>{ if(row.Cells[0].ErrorText!="") { flag=false; //有错误 } } ); if (flag) { dt.AcceptChanges(); } else { MessageBox.Show("注意,你的单元格中仍旧有错误!"); } } void dv_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) { //如果是第一个字段 if (e.ColumnIndex == 0) { int n = 0; //先转化成int类型,尝试转化 if (int.TryParse(e.FormattedValue.ToString(), out n)) { //可以的话,再进一步范围判断 if (n < 1 || n > 100) { dv.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "必须在1~100之内!"; } else { dv.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = ""; } } else { //转换失败,类型都有问题 e.Cancel = true; } } } }}

[VB.NET]

Namespace WinFormCSharp    Public Partial Class Form1        Inherits Form        Private dt As New DataTable()        Private dv As New DataGridView()        Private btn As New Button()        Public Sub New()            InitializeComponent()            dt.Columns.Add("Id", GetType(Integer))            dt.Columns.Add("Name", GetType(String))        End Sub        Private Sub Form1_Load(sender As Object, e As EventArgs)            For i As Integer = 1 To 10                dt.Rows.Add(i, "Name" & i)            Next            dt.AcceptChanges()            dv.Parent = Me            dv.Dock = DockStyle.Fill            dv.DataSource = dt            '添加一个保存到DataTable中的按钮            btn.Parent = Me            btn.Dock = DockStyle.Bottom            btn.Text = "Save To DataTable"            '当不满足条件,该字段为错误            dv.ShowCellErrors = True            '处理单元格验证事件            AddHandler dv.CellValidating, AddressOf dv_CellValidating        End Sub        Private Sub btn_Click(sender As Object, e As EventArgs)            Dim flag As Boolean = True            '默认没有错误            '循环遍历检测是否有错误            dv.Rows.Cast(Of DataGridViewRow)().ToList().ForEach(Function(row)             If row.Cells(0).ErrorText <> "" Then                    '有错误                flag = False            End IfEnd Function)            If flag Then                dt.AcceptChanges()            Else                MessageBox.Show("注意,你的单元格中仍旧有错误!")            End If        End Sub        Private Sub dv_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs)            '如果是第一个字段            If e.ColumnIndex = 0 Then                Dim n As Integer = 0                '先转化成int类型,尝试转化                If Integer.TryParse(e.FormattedValue.ToString(), n) Then                    '可以的话,再进一步范围判断                    If n < 1 OrElse n > 100 Then                        dv.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = "必须在1~100之内!"                    Else                        dv.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = ""                    End If                Else                    '转换失败,类型都有问题                    e.Cancel = True                End If            End If        End Sub    End ClassEnd Namespace
 
标签: ,
参考:

转载于:https://www.cnblogs.com/yhlx125/articles/2465042.html

你可能感兴趣的文章
Debian 考虑重新加入 FFmpeg
查看>>
《淘宝店铺 大数据营销+SEO+爆款打造 一册通》一一1.4 淘宝店铺转化率优化
查看>>
《技术的潜能:商业颠覆、创新与执行》一一1.4基因技术
查看>>
《设计工作室生存手册》—第1章1.5节设计师的工作要有系统
查看>>
《Cisco QoS认证考试指南(第2版)》——6.4节基于类的整形配置
查看>>
《顿悟时刻:设计大师访谈录》—第1章Heinz Edelmann 每过十年,烧掉你的作品集...
查看>>
当极客 (Geek) 遇到呆瓜 (Nerd)
查看>>
Angular 1 vs. Angular 2 深度比较
查看>>
《互联网金融投资理财一册通》导读
查看>>
《vSphere性能设计:性能密集场景下CPU、内存、存储及网络的最佳设计实践》一2.2 性能分析工具...
查看>>
Javascript 闭包与作用域
查看>>
《Python Cookbook(第3版)中文版》——6.5 将字典转换为XML
查看>>
Docker 容器互联方法
查看>>
暗渡陈仓:用低消耗设备进行破解和渗透测试1.2.1 运行Deck的设备
查看>>
C编程vim初步配置
查看>>
阿里云文件存储SMB协议服务及其申请和使用指南
查看>>
《Spring实战(第4版)》——2.6 小结
查看>>
《Java和Android开发学习指南(第2版)》—— 2.8 操作符
查看>>
《PhoneGap移动应用开发手册》——1.3节调整加速计传感器更新时间间隔
查看>>
《HttpClient官方文档》2.5 连接驱逐策略
查看>>