• 数据集中的数据验证代码应该写在什么位置?


    数据集中的数据验证可以通过多种方式来完成:

    (1)通过主键与唯一条件约束来进行唯一性验证;

    (2)通过外键约束来确保数据引用完整性;

    (3)使用字段的相关属性,如AllowDBNull、MaxLength与Unique来辅助完成数据验证操作;

    (4)自行替应用程序书写数据验证代码,以便在字段和记录变更事件期间检查数据。

    前提:在DataGridView控件中修改字段(不包括新行)。

    在默认状态下,每次变更一个字段时将会顺序引发4个事件:首先会引发被更改字段的ColumnChanging与ColumnChanged事件,接着是RowChanging与RowChanged事件。值得注意的是,当修改完一个字段后,焦点离开该字段,但仍在该字段所在行时,仅引发ColumnChanging与ColumnChanged事件,此时可继续修改该行的其它字段,并引发相应事件。一旦焦点离开该行,若焦点离开之前刚修改完一个字段值,不管焦点是否仍落在该列,都将顺序引发4个事件;否则引发被修改行的RowChanging与RowChanged事件。

    Row.BeginEdit()会将记录置于编辑模式。在此模式中,事件将暂时停止以便在不触发字段约束的情况下,对一个记录的多个字段进行修改。而等到调用Row.EndEdit()时,又会触发约束。

    当用户修改数据绑定控件的数据时(如DataGridView控件),会隐式调用被修改行的BeginEdit(),当焦点离开该行时又会隐式调用该行的EndEdit(),从而触发字段约束。(如AllowDBNull、Unique约束等)

    字段值改变会调用4个改变事件,即ColumnChanging、ColumnChanged、RowChanging与RowChanged事件,这时有一个问题,如果自行书写数据验证代码,又该写在的哪个事件中呢?

    我写了一段试验代码,对不同的执行结果进行了分析。

    View Code
            private void DataTableTest4_Load(object sender, EventArgs e)
    {
    string sql = "select * from dbo.客户";
    tbl = Rabbit.DBUtility.DBHelperSql.Query(sql).Tables[0];
    tbl.Columns[0].AllowDBNull = false;
    dataGridView1.DataSource = tbl;
    tbl.Columns["公司名称"].AllowDBNull = false;
    tbl.Columns["公司名称"].DefaultValue = "新世纪公司";

    tbl.ColumnChanging += new DataColumnChangeEventHandler(tbl_ColumnChanging);
    tbl.ColumnChanged += new DataColumnChangeEventHandler(tbl_ColumnChanged);
    tbl.RowChanging += new DataRowChangeEventHandler(tbl_RowChanging);
    tbl.RowChanged += new DataRowChangeEventHandler(tbl_RowChanged);
    }

    private void tbl_ColumnChanging(object sender, DataColumnChangeEventArgs e)
    {
    //e.Row.EndEdit();
    //e.Row.CancelEdit();
    Console.WriteLine(e.Row.RowState.ToString());
    }

    private void tbl_ColumnChanged(object sender, DataColumnChangeEventArgs e)
    {
    //e.Row.CancelEdit();
    //e.Row.EndEdit();
    Console.WriteLine(e.Row.RowState.ToString());
    }

    private void tbl_RowChanging(object sender, DataRowChangeEventArgs e)
    {
    //e.Row.CancelEdit();
    //e.Row.EndEdit();
    Console.WriteLine(e.Row.RowState.ToString());
    }

    private void tbl_RowChanged(object sender, DataRowChangeEventArgs e)
    {
    //e.Row.EndEdit();
    //e.Row.CancelEdit();
    Console.WriteLine(e.Row.RowState.ToString());
    }

    操作:修改DataGridView控件某行(该行不是新行)某列的值,然后焦点离开该行。

    结果:见下面8个表

    表格说明:第1行表示事件,第2行表示在对应事件中调用行的哪个方法,第3行表示事件的执行顺序,第4行表示每次执行对应事件时行的状态,第5行表示执行结果。

    ColumnChanging

    ColumnChanged

    RowChanging

    RowChanged

    EndEdit()

     

     

     

    1/4

    5

    2/6

    3/7

    Unchanged/ Modified

    Modified

    Unchanged/ Modified

    Modified/Modified

    修改成功

     

    ColumnChanging

    ColumnChanged

    RowChanging

    RowChanged

     

    EndEdit()

     

     

    1

    2/5

    3

    4

    Unchanged

    Unchanged/ Modified

    Unchanged

    Modified

    修改成功

     

    ColumnChanging

    ColumnChanged

    RowChanging

    RowChanged

     

     

    EndEdit()

     

    1

    2

    出现异常

     

    Unchanged

    Unchanged

     

     

    不能在RowChanging中调用EndEdit(),同时也不能调用CancelEdit()

     

    ColumnChanging

    ColumnChanged

    RowChanging

    RowChanged

     

     

     

    EndEdit()

    1

    2

    3

    4

    Unchanged

    Unchanged

    Unchanged

    Modified

    修改成功

     

    ColumnChanging

    ColumnChanged

    RowChanging

    RowChanged

     

     

     

     

    1

    2

    3

    4

    Unchanged

    Unchanged

    Unchanged

    Modified

    修改成功

     

    ColumnChanging

    ColumnChanged

    RowChanging

    RowChanged

    CancelEdit()

     

     

     

    1

    2

    3

    4

    Unchanged

    Unchanged

    Unchanged

    Modified

    修改成功

     

    ColumnChanging

    ColumnChanged

    RowChanging

    RowChanged

     

    CancelEdit()

     

     

    1

    2

     

     

    Unchanged

    Unchanged

     

     

    未修改

     

    ColumnChanging

    ColumnChanged

    RowChanging

    RowChanged

     

     

     

    CancelEdit()

    1

    2

    3

    4

    Unchanged

    Unchanged

    Unchanged

    Modified

    修改成功

    结论1:分析上面8个表格的执行结果,可以成功编辑的有6种方案,可以取消编辑的只有1种方案。显而易见,Row.EndEdit()和Row.CancelEdit()在调用条件上是对立的,而这两个方法最好是在一个条件语句的两个对立逻辑下被分别调用。因此,为了满足这一条件,数据验证代码应该写在ColumnChanged事件中;

    结论2:在记录修改成功的6个方案中,该行状态变为Modified都是在调用RowChanged事件时(该事件之后保持Modified是必然的),在此之前,在其它3个事件中行状态都不会由Unchanged变为成功修改后的Modified。

  • 相关阅读:
    排序二——交换排序
    桥接模式 Bridge
    外观模式Facade(解耦)
    装饰模式和代理模式的区别
    代理模式 proxy
    装饰器模式 Decorator
    适配器模式
    android launcher-启动过程
    ubuntu 编译openwrt
    Eclipse Memory Analyzer tool(MAT)
  • 原文地址:https://www.cnblogs.com/2008freestyle/p/2427841.html
Copyright © 2020-2023  润新知