none
关闭窗体前如何取消控件的验证 RRS feed

  • 问题

  • 对datagridview单元格中的数据进行验证,并弹出对话框,目前在关闭窗体时也会进行验证和弹出对话框,如何在关闭窗体时取消验证对话框直接关闭窗体?

    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
            {           
                if (e.ColumnIndex == 1)
                {
                    if (int.Parse(e.FormattedValue.ToString()) > 10 || int.Parse(e.FormattedValue.ToString()) < 0)
                    {
                        e.Cancel = true;
                        MessageBox.Show("输入字符不正确。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                 }
            }
            private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                e.Cancel = false;
            }


    努力~

    2013年6月24日 15:37

答案

  • 对datagridview单元格中的数据进行验证,并弹出对话框,目前在关闭窗体时也会进行验证和弹出对话框,如何在关闭窗体时取消验证对话框直接关闭窗体?

    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
            {           
                if (e.ColumnIndex == 1)
                {
                    if (int.Parse(e.FormattedValue.ToString()) > 10 || int.Parse(e.FormattedValue.ToString()) < 0)
                    {
                        e.Cancel = true;
                        MessageBox.Show("输入字符不正确。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                 }
            }
            private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                e.Cancel = false;
            }


    努力~

    再给你追加一种方式,实现“关闭窗体时取消验证对话框直接关闭窗体”,注意,就是你点击了“关闭”按钮后,不弹出任何对话框,而不论你的 DataGridView 是否处于编辑状态,根据此方法,你可以灵活来运用,以实现允许用户先确认或退出等功能:

    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
           
    {          
               
    if (e.ColumnIndex == 1)
               
    {
                   
    if (int.Parse(e.FormattedValue.ToString()) > 10 || int.Parse(e.FormattedValue.ToString()) < 0)
                   
    {
                        // e
    .Cancel = true我们不需要这个了。
                       
    MessageBox.Show("输入字符不正确。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                   
    }
                
    }
           
    }
           
    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
           
    {
                // e
    .Cancel = false; 我们也不需要这个了。
           
    }

    protected override void WndProc(ref Message m)
            {
                int WM_SYSCOMMAND =0x0112;
                int SC_CLOSE= 0xF060;

                if (m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE)
                {
                    this.dataGridView1.CancelEdit();   // 不管三七二十一,先取消单元格的编辑状态。
                }

                base.WndProc(ref m);
            }

    • 已标记为答案 zjyh16 2013年11月5日 8:43
    2013年8月22日 6:25

全部回复

  • 这个验证应该放在输入的时候。(不合格的内容不给输入即可)

    另外不应该使用messagebox提示,用户要多点一次。体验不好。


    family as water

    2013年6月25日 2:05
  • namespace CSharp
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                DataTable dt = new DataTable();
                dt.Columns.Add("Id"typeof(string));
                for (int i = 0i < 11i++)
                {
                    dt.Rows.Add(i.ToString());
                }
                dataGridView1.AutoGenerateColumns = true;
                dataGridView1.DataSource = dt;
            }
     
            private void dataGridView1_CellValidating(object senderDataGridViewCellValidatingEventArgs e)
            {
                if (e.ColumnIndex == 0)
                {
                    int errorNum = 0;
     
                    if (int.TryParse(e.FormattedValue.ToString(), out errorNum))
                    {
                        if (errorNum >= 10 || errorNum < 0)
                        {
                            MessageBox.Show("数字范围错误!");
                            //加了这句,关闭窗体照样强制改正!
                            //e.Cancel=true;
                            dataGridView1.Rows[e.RowIndex].Cells[0].ErrorText = "数字范围错误";
                        }
                        else
                        {
                            dataGridView1.Rows[e.RowIndex].Cells[0].ErrorText = string.Empty;
                        }
                    }
                    else
                    {
                        MessageBox.Show("必须输入数字!");
                        //加了这句,关闭窗体照样强制改正!
                        //e.Cancel=true;
                        dataGridView1.Rows[e.RowIndex].Cells[0].ErrorText = "必须输入数字";
                    }
                }
            }     
        }
    }

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    2013年6月25日 3:01
    版主
  • 这个验证应该放在输入的时候。(不合格的内容不给输入即可)

    另外不应该使用messagebox提示,用户要多点一次。体验不好。


    family as water

    使用MessageBox只是需求,其实我也不想的。不过问一下,验证放在输入时该怎么做?单元格中只能输入1~10,10-和-。

    努力~

    2013年6月25日 5:37
  • namespace CSharp
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                DataTable dt = new DataTable();
                dt.Columns.Add("Id"typeof(string));
                for (int i = 0i < 11i++)
                {
                    dt.Rows.Add(i.ToString());
                }
                dataGridView1.AutoGenerateColumns = true;
                dataGridView1.DataSource = dt;
            }
     
            private void dataGridView1_CellValidating(object senderDataGridViewCellValidatingEventArgs e)
            {
                if (e.ColumnIndex == 0)
                {
                    int errorNum = 0;
     
                    if (int.TryParse(e.FormattedValue.ToString(), out errorNum))
                    {
                        if (errorNum >= 10 || errorNum < 0)
                        {
                            MessageBox.Show("数字范围错误!");
                            //加了这句,关闭窗体照样强制改正!
                            //e.Cancel=true;
                            dataGridView1.Rows[e.RowIndex].Cells[0].ErrorText = "数字范围错误";
                        }
                        else
                        {
                            dataGridView1.Rows[e.RowIndex].Cells[0].ErrorText = string.Empty;
                        }
                    }
                    else
                    {
                        MessageBox.Show("必须输入数字!");
                        //加了这句,关闭窗体照样强制改正!
                        //e.Cancel=true;
                        dataGridView1.Rows[e.RowIndex].Cells[0].ErrorText = "必须输入数字";
                    }
                }
            }     
        }
    }

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    关闭窗体还是会去验证数据弹出MessageBox,我的要求是关闭窗体时不弹出MessageBox。至于e.Cancel=true,是为了输入错误数据时强制要求更改,就是为了必须先改正错误才加这么一句,如果删去这一句就完全不一样了。

    努力~

    2013年6月25日 5:41
  • 你不必加上e.Cancel=true,请删除Form_Closing事件。

    另外注意我代码注释的部分,你去掉注释看看就明白了,出错自动会强制不允许关闭界面的。


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    2013年6月25日 5:44
    版主
  • 你不必加上e.Cancel=true,请删除Form_Closing事件。

    另外注意我代码注释的部分,你去掉注释看看就明白了,出错自动会强制不允许关闭界面的。


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    不好意思,可能我的意思没讲清楚。不加上e.Cancel=true,就无法将焦点保持在当前单元格,而且我并不希望阻止关闭窗体,而是希望即使有错误也能顺利关闭窗体。

    我的意思是:输入数据有误,焦点保持在当前单元格,并弹出错误提示框,并且此时想要关闭窗体的话就顺利关闭窗体并不提示错误。


    努力~

    2013年6月27日 4:53
  • 首先很抱歉,你的逻辑我不敢苟同:

    如果你输入的数据是错误的,不应当允许关闭界面,因为DataGridView会将错误信息记录到DataTable中去,这个很容易引发写入数据库导致错误。

    此外,如果你一定这样做,我还是强调我一点:

    1)必须删除Form_Closing,否则界面无法正常关闭。

    2)另外附上我的代码,你亲自一试便知:

    namespace CSharp
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                DataTable dt = new DataTable();
                dt.Columns.Add("Id", typeof(string));
                for (int i = 0; i < 11; i++)
                {
                    dt.Rows.Add(i.ToString());
                }
                dataGridView1.AutoGenerateColumns = true;
                dataGridView1.DataSource = dt;
            }
     
            private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
            {
                if (e.ColumnIndex == 0)
                {
                    int errorNum = 0;
     
                    if (int.TryParse(e.FormattedValue.ToString(), out errorNum))
                    {
                        if (errorNum >= 10 || errorNum < 0)
                        {
                            MessageBox.Show("数字范围错误!");
                            //加了这句,关闭窗体照样强制改正!
                            //e.Cancel=true;
                            dataGridView1.Rows[e.RowIndex].Cells[0].ErrorText = "数字范围错误";
                        }
                        else
                        {
                            dataGridView1.Rows[e.RowIndex].Cells[0].ErrorText = string.Empty;
                        }
                    }
                    else
                    {
                        MessageBox.Show("必须输入数字!");
                        //加了这句,关闭窗体照样强制改正!
                        //e.Cancel=true;
                        dataGridView1.Rows[e.RowIndex].Cells[0].ErrorText = "必须输入数字";
                    }
                }
            }     
        }
    } 

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    2013年6月27日 4:57
    版主
  • 一、我用datagridview这个控件,但是这个程序并跟数据库无关,仅仅只是使用这个控件而已,所以不用担心错误数据输入到数据库中。所以我希望能直接关闭程序,因为我可能突然发现其实不需要运行这个程序了。

    二、其次,你的代码我是试过了。由于你这一句e.Cancel=true是注释掉的,在出现错误的数据格式,弹出对话框后点击“确定”按钮后,单元格就失去编辑状态了,而我希望的是该单元格继续保持编辑状态直到输入的数据正确。

    三、但是如果不注释e.Cancel=true,就会阻止关闭窗体,即使在Form_Closing加入e.Cancel=false,也依然会弹出MessageBox。


    努力~

    2013年6月27日 7:00
  • 你似乎没理解LZ的问题,用户要关闭软件,就意味着放弃操作,这时候天王老子都不应该阻止,不能因为验证通不过就不准用户关闭,验证通不过你可以阻止任何后续操作,但不能阻止关闭软件~就这么个意思。
    2013年8月21日 16:06
  • 这篇文档其实有讲到这种需求:

    http://msdn.microsoft.com/zh-cn/library/ms229603(v=vs.90)

    MS的办法是在Closing中令e.Cancel=false,但至于LZ为何无效,有待进一步找原因。

    2013年8月21日 16:11
  • e.Cancel=true这一句貌似不能存在在Cell的验证事件中,否则窗体无法正常关闭。

    如果你不希望MsgBox弹出来,那么可以连同把这些一起注释掉,只要在单元格上显示红色的“!”应该就可以提示用户了,在Update按钮事件中检测行列是否带有错误即可,没有才允许更新,这样既可以保证更新时没有错误,同时也可以关闭窗体。


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    2013年8月22日 1:40
    版主
  • 对datagridview单元格中的数据进行验证,并弹出对话框,目前在关闭窗体时也会进行验证和弹出对话框,如何在关闭窗体时取消验证对话框直接关闭窗体?

    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
            {           
                if (e.ColumnIndex == 1)
                {
                    if (int.Parse(e.FormattedValue.ToString()) > 10 || int.Parse(e.FormattedValue.ToString()) < 0)
                    {
                        e.Cancel = true;
                        MessageBox.Show("输入字符不正确。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                 }
            }
            private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                e.Cancel = false;
            }


    努力~

    虽然你可能还需要更精细的控制,以提示用户是否在关闭窗体前需要保存修改,但是下面的代码可以让你看到你想要的结果:

    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
           
    {          
               
    if (e.ColumnIndex == 1)
               
    {
                   
    if (int.Parse(e.FormattedValue.ToString()) > 10 || int.Parse(e.FormattedValue.ToString()) < 0)
                   
    {
                        //e
    .Cancel = true;  这个不要。
                       
    MessageBox.Show("输入字符不正确。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                   
    }
                
    }
           
    }
           
    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
           
    {
                // e
    .Cancel = false; 这个也不要。

                this.dataGridView1.CancelEdit();   // 不管三七二十一,先取消单元格的编辑状态。
           
    }

    2013年8月22日 2:22
  • CellValidating中的e.Cancel=true必须的,不然就不会有这个问题了,LZ要的是,验证通不过的情况下,阻止离开单元格~除非关闭软件。

    我自己的情况是,MS的办法是有效的,即在FormClosing中加入e.Cancel = false,就可以实现上述目的,阻止其它操作的同时允许关闭窗体。

    2013年8月22日 4:02
  • 对datagridview单元格中的数据进行验证,并弹出对话框,目前在关闭窗体时也会进行验证和弹出对话框,如何在关闭窗体时取消验证对话框直接关闭窗体?

    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
            {           
                if (e.ColumnIndex == 1)
                {
                    if (int.Parse(e.FormattedValue.ToString()) > 10 || int.Parse(e.FormattedValue.ToString()) < 0)
                    {
                        e.Cancel = true;
                        MessageBox.Show("输入字符不正确。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                 }
            }
            private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                e.Cancel = false;
            }


    努力~

    再给你追加一种方式,实现“关闭窗体时取消验证对话框直接关闭窗体”,注意,就是你点击了“关闭”按钮后,不弹出任何对话框,而不论你的 DataGridView 是否处于编辑状态,根据此方法,你可以灵活来运用,以实现允许用户先确认或退出等功能:

    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
           
    {          
               
    if (e.ColumnIndex == 1)
               
    {
                   
    if (int.Parse(e.FormattedValue.ToString()) > 10 || int.Parse(e.FormattedValue.ToString()) < 0)
                   
    {
                        // e
    .Cancel = true我们不需要这个了。
                       
    MessageBox.Show("输入字符不正确。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                   
    }
                
    }
           
    }
           
    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
           
    {
                // e
    .Cancel = false; 我们也不需要这个了。
           
    }

    protected override void WndProc(ref Message m)
            {
                int WM_SYSCOMMAND =0x0112;
                int SC_CLOSE= 0xF060;

                if (m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE)
                {
                    this.dataGridView1.CancelEdit();   // 不管三七二十一,先取消单元格的编辑状态。
                }

                base.WndProc(ref m);
            }

    • 已标记为答案 zjyh16 2013年11月5日 8:43
    2013年8月22日 6:25
  • CellValidating中不用e.Cancel = true的话,验证通不过时如何阻止单元格离开?LZ要的是又要阻止离开,又要能关闭窗体。其实MS已经给出办法,就是在FormClosing中加入e.Cancel = false
    2013年8月22日 8:07
  • CellValidating中不用e.Cancel = true的话,验证通不过时如何阻止单元格离开?LZ要的是又要阻止离开,又要能关闭窗体。其实MS已经给出办法,就是在FormClosing中加入e.Cancel = false

    你试过?在DataGridView出错情况下照样可以关闭?

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    2013年8月22日 9:03
    版主
  • 是的,我试过,MS的办法有效。
    2013年8月23日 3:10
  • 其实答案不是很简单吗?你处在编辑状态去关闭窗口,事件引发的顺序必定是先验证后关闭,验证不通过必定要弹出窗口,这是必然的事情,与FormClosing设置无关。如果非要强制关闭,我想大概唯一的办法就是焦点测试,获取鼠标焦点坐标是否在关闭按钮上,如果是直接调用ShutDown方法,,当然这不是因为你单击关闭按钮关闭了窗口,而是验证事件发生时,鼠标坐标满足在你规定的窗口坐标区域内。你可以用这个方法试试,在验证事件代码内加入焦点坐标测试,如果鼠标坐标在关闭按钮上,直接调用窗体关闭代码。
    2013年8月24日 15:47
  • 补充一点就是,验证事件发生在单元格失去焦点时,属于焦点事件,应该是发生在你单击关闭按钮的事件之前的。要在关闭窗口前避免弹窗,关闭代码要在弹窗代码前面。
    2013年8月24日 15:50
  • 都说了FormClosing中e.Cancel = false就行了,这都扯到鼠标坐标去了
    2013年11月2日 2:53