TextBox和DataGridView控件的事件发生顺序

今天在编写代码的时候碰到了控件的验证问题。

命题:在前台的DataGridView中,任意行的单元格都不能为空,也就是说,在编写的过程中,某一行的编辑完成之后,需要验证各单元是否为空。

事件绑定:最开始编写的时候,我调用了dgvDetail.RowLeave事件。发现每次鼠标移到其他行的时候,最后一个编写的单元数据还没有写入之前就开始执行RowLeave事件了。也就是说,用户已经填写了数据,但是在数据写入控件之间就先执行验证事件了。这样的操作过程对用户来讲是非常不友好的。

然后我做了一个调整,将验证事件绑在了dgvDetail.RowValidated上。

随后我做了一个控件事件的发生顺序以及赋值情况的测试。

测试对象:TextBox、DataGridView.前台窗口如下:

后台代码如下:

public partial class TestEvent : Form
{
    string txtEventStr = "", dgvEventStr = "";
    int txtI = 0, dgvI = 0;
    public TestEvent()
    {
        InitializeComponent();
        Action<string> txtAdd = txt =>
        {
            txtI++;
            txtEventStr += string.Format("\r\n{0}:{1}, Text = {2}", txtI, txt, txtEventTest.Text);
        };
        Action<string> dgvStrAdd = txt =>
        {
            dgvI++;
            dgvEventStr += string.Format("\r\n{0}:{1}, Text = {2}", dgvI, txt, dgv[0, 0].Value);
        };
        txtEventTest.Validated += (a, b) => txtAdd("Validated");
        txtEventTest.Validating += (a, b) => txtAdd("Validating");
        txtEventTest.Leave += (a, b) => txtAdd("Leave");
        txtEventTest.LostFocus += (a, b) => txtAdd("LostFocus");
        txtEventTest.GotFocus += (a, b) => txtAdd("GotFocus");
        txtEventTest.Enter += (a, b) => txtAdd("Enter");
        btnTxtEvent.Click += (a, b) => MessageBox.Show(txtEventStr);

        dgv.RowEnter += (a, b) => dgvStrAdd("RowEnter");
        dgv.RowValidated += (a, b) => dgvStrAdd("RowValidated");
        dgv.RowValidating += (a, b) => dgvStrAdd("RowValidating");
        dgv.RowLeave += (a, b) => dgvStrAdd("RowLeave");
        btnDGVEvent.Click += (a, b) => MessageBox.Show(dgvEventStr);
    }
}

 前台操作:

鼠标点击textbox => 输入文字 => 点击按钮btnTxtEvent。

鼠标点击dgv的[0,0]单元  => 输入文字 => 点击按钮btnDGVEvent。

执行结果:

  

根据最后的执行结果,我们可以清晰的看到textBox的事件执行顺序为Enter、GotFocus、LostFocus、Leave、Validating、Validated,也就是说程序先“进入”控件,然后控件“得到焦点”,紧接着控件“失去焦点”,此时前台输入的值已经写入控件属性,然后“离开”控件,开始“校验”,最后发生“校验完”事件。

而DataGridView的行事件执行顺序为RowEnter、RowLeave、RowValidating、RowValidated,顺序与textBox的事件执行顺序可以说一致,但有一个很大的区别,前台输入值写入控件的时间。相较于textbox在Leave事件之前就写入,DataGridView却是在RowLeave事件之后才写入控件的属性。因此,回到最开始的命题中,才会导致那样不友好的操作结果。

以上内容为笔者亲著,转发请注明本文地址:

http://www.cnblogs.com/icyJ/archive/2012/10/29/Event_Order.html

posted @ 2012-10-29 15:43  脸谱匠  阅读(2514)  评论(0编辑  收藏  举报