tab页签切换时,datagridview单元格校验失败,导致datagridview表格无法再进入编辑状态。

时间:2021-08-30 09:58:24
最近在做一个包含了多个tab、表格的复杂控件,遇到了一个很纠结的问题,问题可以简略为以下的demo:

窗体代码

namespace WindowsFormsApplication3
{
    partial class Form1
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.tabControl1 = new System.Windows.Forms.TabControl();
            this.tabPage1 = new System.Windows.Forms.TabPage();
            this.tabPage2 = new System.Windows.Forms.TabPage();
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column3 = new System.Windows.Forms.DataGridViewComboBoxColumn();
            this.tabControl1.SuspendLayout();
            this.tabPage2.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            this.SuspendLayout();
            // 
            // tabControl1
            // 
            this.tabControl1.Controls.Add(this.tabPage1);
            this.tabControl1.Controls.Add(this.tabPage2);
            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tabControl1.Location = new System.Drawing.Point(0, 0);
            this.tabControl1.Name = "tabControl1";
            this.tabControl1.SelectedIndex = 0;
            this.tabControl1.Size = new System.Drawing.Size(284, 262);
            this.tabControl1.TabIndex = 0;
            // 
            // tabPage1
            // 
            this.tabPage1.Location = new System.Drawing.Point(4, 22);
            this.tabPage1.Name = "tabPage1";
            this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage1.Size = new System.Drawing.Size(276, 236);
            this.tabPage1.TabIndex = 0;
            this.tabPage1.Text = "tabPage1";
            this.tabPage1.UseVisualStyleBackColor = true;
            // 
            // tabPage2
            // 
            this.tabPage2.Controls.Add(this.dataGridView1);
            this.tabPage2.Location = new System.Drawing.Point(4, 22);
            this.tabPage2.Name = "tabPage2";
            this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage2.Size = new System.Drawing.Size(276, 236);
            this.tabPage2.TabIndex = 1;
            this.tabPage2.Text = "tabPage2";
            this.tabPage2.UseVisualStyleBackColor = true;
            // 
            // dataGridView1
            // 
            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.Column1,
            this.Column2,
            this.Column3});
            this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridView1.Location = new System.Drawing.Point(3, 3);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.RowTemplate.Height = 23;
            this.dataGridView1.Size = new System.Drawing.Size(270, 230);
            this.dataGridView1.TabIndex = 0;
            this.dataGridView1.CellValidating += new System.Windows.Forms.DataGridViewCellValidatingEventHandler(this.dataGridView1_CellValidating);
            // 
            // Column1
            // 
            this.Column1.HeaderText = "Column1";
            this.Column1.Name = "Column1";
            // 
            // Column2
            // 
            this.Column2.HeaderText = "Column2";
            this.Column2.Name = "Column2";
            // 
            // Column3
            // 
            this.Column3.HeaderText = "Column3";
            this.Column3.Items.AddRange(new object[] {
            "hello1",
            "hello2"});
            this.Column3.Name = "Column3";
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 262);
            this.Controls.Add(this.tabControl1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.tabControl1.ResumeLayout(false);
            this.tabPage2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.TabControl tabControl1;
        private System.Windows.Forms.TabPage tabPage1;
        private System.Windows.Forms.TabPage tabPage2;
        private System.Windows.Forms.DataGridView dataGridView1;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
        private System.Windows.Forms.DataGridViewComboBoxColumn Column3;
    }
}






using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if(e.ColumnIndex==-1||e.RowIndex==-1)
            {
                return;
            }
            if(string.IsNullOrEmpty(e.FormattedValue.ToString()))
            {
                return;
            }
            int value = 0;
            if(!int.TryParse(e.FormattedValue.ToString(),out value))
            {
                e.Cancel = true;
                dataGridView1.CancelEdit();
                MessageBox.Show(this, "Erro Data.");
            }
        }
    }
}





描述:一个很简单的窗体,包含一个tab及表格,后台逻辑就是如果输入是非数字,触发cellValidate校验,并做提示。
问题复现步骤:
1,打开窗体
2,切换到第二页签,在column1上输入一个非数字字符,然后直接点击tabPage1。出现结果1.
实际结果:
1,提示校验“Data Erro.”
   点击column3,下拉选项无法显示,再点击column1,column2,无法进入编辑状态,但是可以直接输值。
期望结果:
点击column3能够选择下拉选项,点击column1,column2能够进入编辑状态。


特别注明:
1,希望在切换tab时,如果表格校验非法,需要提示并留在当前tabpage。
因为实际场景中,表格校验很复杂,分了cell和row两种校验,需要先保证cell校验是合法的,不然row校验会崩溃,所以必须触发cellvalidate,所以CausesValidation需要设置为true。
2,上述后台代码,如果去掉 
MessageBox.Show(this, "Erro Data.");
那么不会出现上面那个问题。(所以说是微软的一个bug???)

18 个解决方案

#1


遇到过类似的问题,不过当时是Silverlight的,不知道WinForm的事件和方法是否一致。
当时问题是:tab1里面有输入框,需要验证,如果输入内容,并且直接点击tab2,则会跳转到tab2,并且会弹出:输入错误框。
解决方法:添加Tab的切换事件,并且定义Flag:IsAllowChangTab(是否需要切换tab),如果验证不通过则设置为false,然后在Tab的切换事件中,判断IsAllowChangTab,如果是false,则再次切换到原来的Tab。
没有找到更好的方法,当然这是在Silverlight中,而且验证事件在切换事件前,希望帮到你。

#2


引用 1 楼 osnot 的回复:
遇到过类似的问题,不过当时是Silverlight的,不知道WinForm的事件和方法是否一致。
当时问题是:tab1里面有输入框,需要验证,如果输入内容,并且直接点击tab2,则会跳转到tab2,并且会弹出:输入错误框。
解决方法:添加Tab的切换事件,并且定义Flag:IsAllowChangTab(是否需要切换tab),如果验证不通过则设置为false,然后在Tab的切换事件中,判断IsAllowChangTab,如果是false,则再次切换到原来的Tab。
没有找到更好的方法,当然这是在Silverlight中,而且验证事件在切换事件前,希望帮到你。

谢谢,不过我并不是切换不了的问题。

#3


木有人晓得么,100分哦,混分的都没一个咩

#4


抱歉,昨天太懒了,没有写代码。今天写了一点代码,刚开始以为是TabControl的问题,后来测试发现是DataGridView的问题,以为弹出一个对话框后,DataGridView可能会失去焦点,或者编辑模式变了,后来发现没有变,再后来发现还是TabControl的问题,因为它实际已经激活了另外一个选项卡,但是画面时停留在现在(包含GridView的选项卡),所以导致了这个问题,解决方法和Silverlight一样。。。
代码(Form1.Designer.cs)-增加了tabControl1.Deselecting事件:

...
this.tabControl1.Deselecting += new System.Windows.Forms.TabControlCancelEventHandler(this.tabControl1_Deselecting);
...

然后后台cs文件:

public partial class Form1 : Form
    {
        private bool isDataGridViewValidateError = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if(e.ColumnIndex==-1||e.RowIndex==-1)
            {
                return;
            }
            if(string.IsNullOrEmpty(e.FormattedValue.ToString()))
            {
                return;
            }
            int value = 0;
            if(!int.TryParse(e.FormattedValue.ToString(),out value))
            {
                //e.Cancel = true;
                dataGridView1.CancelEdit();
                MessageBox.Show(this, "Erro Data.");
                isDataGridViewValidateError = true;
            }
        }

        private void tabControl1_Deselecting(object sender, TabControlCancelEventArgs e)
        {
            if (isDataGridViewValidateError == true)
            {
                e.Cancel = true;
                isDataGridViewValidateError = false;
            }
        }
    }

如上面代码,把e.Cancel = true;注掉了,因为如果设置为true的话,就不会出发TabContorl的切换事件,而实际已经切换过去了,所以会出问题,解决办法是在这个事件中取消切换。
测试通过,希望帮到你。

#5


上面的代码有问题:当输入完非数字后,我点击另外一个cell,这时会弹出提示对话框,然后我点击第一个tab是没有反应的,因为isDataGridViewValidateError = true;我又查了很多文档,终于利用关键字:datagridview CellValidating tabControl 在google上搜索到了:http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/c3634471-49cb-4274-afa4-c4bcd184b52c
在2009/02/19号就有人在MSDN上提交这个Bug了,MSDN回复说:已经反馈给开发小组,可是现在还是这样,应该是MS的一个Bug。
如果有解决方法,记得通知我。
谢谢。

#6


引用 5 楼 osnot 的回复:
上面的代码有问题:当输入完非数字后,我点击另外一个cell,这时会弹出提示对话框,然后我点击第一个tab是没有反应的,因为isDataGridViewValidateError = true;我又查了很多文档,终于利用关键字:datagridview CellValidating tabControl 在google上搜索到了:http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/c3634471-49cb-4274-afa4-c4bcd184b52c
在2009/02/19号就有人在MSDN上提交这个Bug了,MSDN回复说:已经反馈给开发小组,可是现在还是这样,应该是MS的一个Bug。
如果有解决方法,记得通知我。
谢谢。



已经解决了
http://www.cnblogs.com/suriyel/p/3166086.html

#7


唔,我会的,也遇到过这种问题,不过你解决了就算了。

#8


引用 7 楼 yixian2007 的回复:
唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

#9


不使用e.cancel = true就行了。

引用 8 楼 osnot 的回复:
Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

#10


引用 9 楼 yixian2007 的回复:
不使用e.cancel = true就行了。

Quote: 引用 8 楼 osnot 的回复:

Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

不用e.cancel = true会有问题的。

#11


引用 10 楼 osnot 的回复:
Quote: 引用 9 楼 yixian2007 的回复:

不使用e.cancel = true就行了。

Quote: 引用 8 楼 osnot 的回复:

Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

不用e.cancel = true会有问题的。


啥问题,你提示他错了,然后把它输入的值置为一个默认的合法值就行了,或者设定为空值。你使用e.cancel就把后续的所有操作全停了。

#12


引用 11 楼 yixian2007 的回复:
Quote: 引用 10 楼 osnot 的回复:

Quote: 引用 9 楼 yixian2007 的回复:

不使用e.cancel = true就行了。

Quote: 引用 8 楼 osnot 的回复:

Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

不用e.cancel = true会有问题的。


啥问题,你提示他错了,然后把它输入的值置为一个默认的合法值就行了,或者设定为空值。你使用e.cancel就把后续的所有操作全停了。




e.Cancel不赋值的话,正常的cell校验就失效了

#13


引用 12 楼 Suriyel 的回复:
Quote: 引用 11 楼 yixian2007 的回复:

Quote: 引用 10 楼 osnot 的回复:

Quote: 引用 9 楼 yixian2007 的回复:

不使用e.cancel = true就行了。

Quote: 引用 8 楼 osnot 的回复:

Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

不用e.cancel = true会有问题的。


啥问题,你提示他错了,然后把它输入的值置为一个默认的合法值就行了,或者设定为空值。你使用e.cancel就把后续的所有操作全停了。




e.Cancel不赋值的话,正常的cell校验就失效了


既然你如此纠结,告诉你个终极的解决方法,自定义列,将列自定义,这样当进入编辑模式时,进入的是自定义的控件,不使用datagridview的验证了,直接在textbox中验证。验证不通过不离开textbox,这样的情况连datagridview都回不到,更别提点什么tab了。
其实正常的校验你不理它就可以了,给他个提示错误,然后重置,正常的校验怎么不行?

#14


其实这个无非是想让第2个TAB里面的GRID里不能输入非数字是吧,做的方法很多
一,像楼上那样做个隐藏的TEXT 绑定列。
二,不采用你原先的cellvalidate 而是用cellbeginedit,来判断它是否进入编辑状态,返回一个布尔值,然后在这个GRID的keydown事件里 截取按键 这样可以实现 非数字键都无法输入
三,如果设计式样允许,做个小型子页面,这个画面的CELL是不可编辑的,双击CELL弹出子画面,子画面的TEXTBOX等 进行赋值 

#15


引用 14 楼 czz65979674 的回复:
其实这个无非是想让第2个TAB里面的GRID里不能输入非数字是吧,做的方法很多
一,像楼上那样做个隐藏的TEXT 绑定列。
二,不采用你原先的cellvalidate 而是用cellbeginedit,来判断它是否进入编辑状态,返回一个布尔值,然后在这个GRID的keydown事件里 截取按键 这样可以实现 非数字键都无法输入
三,如果设计式样允许,做个小型子页面,这个画面的CELL是不可编辑的,双击CELL弹出子画面,子画面的TEXTBOX等 进行赋值 


就用户体验感,来说第二种要比第三种要好
第二种是可行的,但是有个问题,就是将校验耦合到了view控件层,不利于校验逻辑或该控件的复用

#16


切换时加个判断if(dataGri1.DataSource!=null)
{
....................................
}

#17


都这么久都没结贴,楼主不厚道。

#18


实现DataGridView控件中验证数据输入功能主要是利用DataGridView控件的公共事件CellValidating和CellEndEdit事件在为当前选定的单元格停止编辑模式时发生。本实例判断控件第一列中单元格的值是否为空。在CellValidating事件中进行验证,如果严重失败,将System.Windows.Forms.DataGridViewCellValidatingEventArgs类的Cancel属性设置为True。这将导致DataGridView控件阻止光标离开该单元格。将该行的ErrorText属性设置为解释性字符串,将显示错误图标,其工具提示将保护此错误文本。在CellEndEdit事件处理程序中,将该行的ErrorText属性设置为空字符串。只有当单元格退出编辑模式(如果验证失败,则不能退出单元格)时,才能发生CellEndEdit事件。运动程序,编辑控件的第一列,在单元格中不输入内容,然后使用鼠标单击其他单元格,这样就会提示错误
下面给出大家主要代码:
 
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;
         }
     }
}
Private void dataGridView1_CellEndEdit(object sender,DataGridViewCellEventArgs e)
{
      dataGridView1.Rows[e.RowIndex].ErrorText=String.Empty;
}
__________________________________________________________________________________________
draw code128 in c#.net draw code128 in c#.net

#1


遇到过类似的问题,不过当时是Silverlight的,不知道WinForm的事件和方法是否一致。
当时问题是:tab1里面有输入框,需要验证,如果输入内容,并且直接点击tab2,则会跳转到tab2,并且会弹出:输入错误框。
解决方法:添加Tab的切换事件,并且定义Flag:IsAllowChangTab(是否需要切换tab),如果验证不通过则设置为false,然后在Tab的切换事件中,判断IsAllowChangTab,如果是false,则再次切换到原来的Tab。
没有找到更好的方法,当然这是在Silverlight中,而且验证事件在切换事件前,希望帮到你。

#2


引用 1 楼 osnot 的回复:
遇到过类似的问题,不过当时是Silverlight的,不知道WinForm的事件和方法是否一致。
当时问题是:tab1里面有输入框,需要验证,如果输入内容,并且直接点击tab2,则会跳转到tab2,并且会弹出:输入错误框。
解决方法:添加Tab的切换事件,并且定义Flag:IsAllowChangTab(是否需要切换tab),如果验证不通过则设置为false,然后在Tab的切换事件中,判断IsAllowChangTab,如果是false,则再次切换到原来的Tab。
没有找到更好的方法,当然这是在Silverlight中,而且验证事件在切换事件前,希望帮到你。

谢谢,不过我并不是切换不了的问题。

#3


木有人晓得么,100分哦,混分的都没一个咩

#4


抱歉,昨天太懒了,没有写代码。今天写了一点代码,刚开始以为是TabControl的问题,后来测试发现是DataGridView的问题,以为弹出一个对话框后,DataGridView可能会失去焦点,或者编辑模式变了,后来发现没有变,再后来发现还是TabControl的问题,因为它实际已经激活了另外一个选项卡,但是画面时停留在现在(包含GridView的选项卡),所以导致了这个问题,解决方法和Silverlight一样。。。
代码(Form1.Designer.cs)-增加了tabControl1.Deselecting事件:

...
this.tabControl1.Deselecting += new System.Windows.Forms.TabControlCancelEventHandler(this.tabControl1_Deselecting);
...

然后后台cs文件:

public partial class Form1 : Form
    {
        private bool isDataGridViewValidateError = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if(e.ColumnIndex==-1||e.RowIndex==-1)
            {
                return;
            }
            if(string.IsNullOrEmpty(e.FormattedValue.ToString()))
            {
                return;
            }
            int value = 0;
            if(!int.TryParse(e.FormattedValue.ToString(),out value))
            {
                //e.Cancel = true;
                dataGridView1.CancelEdit();
                MessageBox.Show(this, "Erro Data.");
                isDataGridViewValidateError = true;
            }
        }

        private void tabControl1_Deselecting(object sender, TabControlCancelEventArgs e)
        {
            if (isDataGridViewValidateError == true)
            {
                e.Cancel = true;
                isDataGridViewValidateError = false;
            }
        }
    }

如上面代码,把e.Cancel = true;注掉了,因为如果设置为true的话,就不会出发TabContorl的切换事件,而实际已经切换过去了,所以会出问题,解决办法是在这个事件中取消切换。
测试通过,希望帮到你。

#5


上面的代码有问题:当输入完非数字后,我点击另外一个cell,这时会弹出提示对话框,然后我点击第一个tab是没有反应的,因为isDataGridViewValidateError = true;我又查了很多文档,终于利用关键字:datagridview CellValidating tabControl 在google上搜索到了:http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/c3634471-49cb-4274-afa4-c4bcd184b52c
在2009/02/19号就有人在MSDN上提交这个Bug了,MSDN回复说:已经反馈给开发小组,可是现在还是这样,应该是MS的一个Bug。
如果有解决方法,记得通知我。
谢谢。

#6


引用 5 楼 osnot 的回复:
上面的代码有问题:当输入完非数字后,我点击另外一个cell,这时会弹出提示对话框,然后我点击第一个tab是没有反应的,因为isDataGridViewValidateError = true;我又查了很多文档,终于利用关键字:datagridview CellValidating tabControl 在google上搜索到了:http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/c3634471-49cb-4274-afa4-c4bcd184b52c
在2009/02/19号就有人在MSDN上提交这个Bug了,MSDN回复说:已经反馈给开发小组,可是现在还是这样,应该是MS的一个Bug。
如果有解决方法,记得通知我。
谢谢。



已经解决了
http://www.cnblogs.com/suriyel/p/3166086.html

#7


唔,我会的,也遇到过这种问题,不过你解决了就算了。

#8


引用 7 楼 yixian2007 的回复:
唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

#9


不使用e.cancel = true就行了。

引用 8 楼 osnot 的回复:
Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

#10


引用 9 楼 yixian2007 的回复:
不使用e.cancel = true就行了。

Quote: 引用 8 楼 osnot 的回复:

Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

不用e.cancel = true会有问题的。

#11


引用 10 楼 osnot 的回复:
Quote: 引用 9 楼 yixian2007 的回复:

不使用e.cancel = true就行了。

Quote: 引用 8 楼 osnot 的回复:

Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

不用e.cancel = true会有问题的。


啥问题,你提示他错了,然后把它输入的值置为一个默认的合法值就行了,或者设定为空值。你使用e.cancel就把后续的所有操作全停了。

#12


引用 11 楼 yixian2007 的回复:
Quote: 引用 10 楼 osnot 的回复:

Quote: 引用 9 楼 yixian2007 的回复:

不使用e.cancel = true就行了。

Quote: 引用 8 楼 osnot 的回复:

Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

不用e.cancel = true会有问题的。


啥问题,你提示他错了,然后把它输入的值置为一个默认的合法值就行了,或者设定为空值。你使用e.cancel就把后续的所有操作全停了。




e.Cancel不赋值的话,正常的cell校验就失效了

#13


引用 12 楼 Suriyel 的回复:
Quote: 引用 11 楼 yixian2007 的回复:

Quote: 引用 10 楼 osnot 的回复:

Quote: 引用 9 楼 yixian2007 的回复:

不使用e.cancel = true就行了。

Quote: 引用 8 楼 osnot 的回复:

Quote: 引用 7 楼 yixian2007 的回复:

唔,我会的,也遇到过这种问题,不过你解决了就算了。

请问你怎么解决的?

不用e.cancel = true会有问题的。


啥问题,你提示他错了,然后把它输入的值置为一个默认的合法值就行了,或者设定为空值。你使用e.cancel就把后续的所有操作全停了。




e.Cancel不赋值的话,正常的cell校验就失效了


既然你如此纠结,告诉你个终极的解决方法,自定义列,将列自定义,这样当进入编辑模式时,进入的是自定义的控件,不使用datagridview的验证了,直接在textbox中验证。验证不通过不离开textbox,这样的情况连datagridview都回不到,更别提点什么tab了。
其实正常的校验你不理它就可以了,给他个提示错误,然后重置,正常的校验怎么不行?

#14


其实这个无非是想让第2个TAB里面的GRID里不能输入非数字是吧,做的方法很多
一,像楼上那样做个隐藏的TEXT 绑定列。
二,不采用你原先的cellvalidate 而是用cellbeginedit,来判断它是否进入编辑状态,返回一个布尔值,然后在这个GRID的keydown事件里 截取按键 这样可以实现 非数字键都无法输入
三,如果设计式样允许,做个小型子页面,这个画面的CELL是不可编辑的,双击CELL弹出子画面,子画面的TEXTBOX等 进行赋值 

#15


引用 14 楼 czz65979674 的回复:
其实这个无非是想让第2个TAB里面的GRID里不能输入非数字是吧,做的方法很多
一,像楼上那样做个隐藏的TEXT 绑定列。
二,不采用你原先的cellvalidate 而是用cellbeginedit,来判断它是否进入编辑状态,返回一个布尔值,然后在这个GRID的keydown事件里 截取按键 这样可以实现 非数字键都无法输入
三,如果设计式样允许,做个小型子页面,这个画面的CELL是不可编辑的,双击CELL弹出子画面,子画面的TEXTBOX等 进行赋值 


就用户体验感,来说第二种要比第三种要好
第二种是可行的,但是有个问题,就是将校验耦合到了view控件层,不利于校验逻辑或该控件的复用

#16


切换时加个判断if(dataGri1.DataSource!=null)
{
....................................
}

#17


都这么久都没结贴,楼主不厚道。

#18


实现DataGridView控件中验证数据输入功能主要是利用DataGridView控件的公共事件CellValidating和CellEndEdit事件在为当前选定的单元格停止编辑模式时发生。本实例判断控件第一列中单元格的值是否为空。在CellValidating事件中进行验证,如果严重失败,将System.Windows.Forms.DataGridViewCellValidatingEventArgs类的Cancel属性设置为True。这将导致DataGridView控件阻止光标离开该单元格。将该行的ErrorText属性设置为解释性字符串,将显示错误图标,其工具提示将保护此错误文本。在CellEndEdit事件处理程序中,将该行的ErrorText属性设置为空字符串。只有当单元格退出编辑模式(如果验证失败,则不能退出单元格)时,才能发生CellEndEdit事件。运动程序,编辑控件的第一列,在单元格中不输入内容,然后使用鼠标单击其他单元格,这样就会提示错误
下面给出大家主要代码:
 
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;
         }
     }
}
Private void dataGridView1_CellEndEdit(object sender,DataGridViewCellEventArgs e)
{
      dataGridView1.Rows[e.RowIndex].ErrorText=String.Empty;
}
__________________________________________________________________________________________
draw code128 in c#.net draw code128 in c#.net