1.子类DTable,继承自DataTable;
子类DRow,继承自DataRow;
DRow包含一个属性:StateFlag2.DTable的TableNewRow事件中,
设置DRow的StateFlag的值。3.问题出现了:   DTable dt = new DTalbe();
   adpter.Fill(dt);//不触发任何添加行的事件
   DRow row = dt.NewRow();
   dt.Rows.Add(row);//不触发任何添加行的事件那么DataTable的事件,
将是在什么样的情况下触发呢?
万分感谢。

解决方案 »

  1.   

    触发DataTable的什么事件呢?是在哪里触发呢?
      

  2.   

    使用 NewRow 创建 DataRow 后激发。在调用的 NewRow 方法返回前激发该事件。新 DataRow 实例被分离,它尚未添加到集合中。
    我写的一个小测试程序如下:StateFlag在创建行时变成了10,而非0using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;namespace answerconsole
    {
        class Program
        {
            public void MyTableNewRow(Object sender, DataTableNewRowEventArgs e)
            {
                DRow.StateFlag = 10;
                Console.WriteLine(DRow.StateFlag.ToString());
            }
            static void Main(string[] args)
            {
                Program p = new Program();
                DTable DataTable1 = new DTable();    
                 DataTable1.TableNewRow  += new DataTableNewRowEventHandler(p.MyTableNewRow);
                 DataRow tow = DataTable1.NewRow();
                 Console.ReadLine();
            }
        }
        public class DTable : DataTable
        {    }
        public class DRow : DataRow
        {        public static int StateFlag = 0;
            public DRow():base(null)
            {
                
            }
        }
      
    }
      

  3.   

    向数据表中添加数据
    .NET Framework 4 其他版本  Visual Studio 2008 Visual Studio 2005 在创建 DataTable 并使用列和约束定义其结构之后,您可以将新的数据行添加到表中。 要添加新行,可将一个新变量声明为 DataRow 类型。 调用 NewRow 方法时,将返回新的 DataRow 对象。 然后,DataTable 会根据 DataColumnCollection 定义的表结构创建 DataRow 对象。 以下示例演示了如何通过调用 NewRow 方法来创建新行。VBC#C++F#JScript复制DataRow workRow = workTable.NewRow();然后您可以使用索引或列名来处理新添加的行,如下例所示。VBC#C++F#JScript复制workRow["CustLName"] = "Smith";
    workRow[1] = "Smith";在将数据插入新行后,Add 方法可用于将行添加到 DataRowCollection,如以下代码所示。VBC#C++F#JScript复制workTable.Rows.Add(workRow);您也可以通过传入值的数组(类型化为 Object),调用 Add 方法来添加新行,如下例所示。VBC#C++F#JScript复制workTable.Rows.Add(new Object[] {1, "Smith"});将类型化为 Object 的值的数组传递到 Add 方法,可在表内创建新行并将其列值设置为对象数组中的值。 请注意,数组中的值会根据它们在表中出现的顺序相继与各列匹配。 以下示例向新建的 Customers 表中添加了 10 行。VBC#C++F#JScript复制DataRow workRow;for (int i = 0; i <= 9; i++) 
    {
      workRow = workTable.NewRow();
      workRow[0] = i;
      workRow[1] = "CustName" + i.ToString();
      workTable.Rows.Add(workRow);
    }
      

  4.   

    你重写 NewRow 方法了?
      

  5.   

    public new DTable() : base(){}
    看看DTable的TableNewRow事件代码
      

  6.   


    没有,我override了TableNewRow事件,但是该事件不能被触发。我把断点设在i=1;语句上。在NewRow()和Fill()的时候,都没有跳到这儿。protected override void OnTableNewRow(DataTableNewRowEventArgs e)
            {
                int i = 1;
                base.OnTableNewRow(e);
            }
      

  7.   

    public DTable() : base()
            {
                this.TableNewRow += (sender, e) =>
                {
                      var row = e.Row;
                      int i = 1;                 
                };
            }
      

  8.   


    非常感谢,这样确实是可行的。
    只是我有点疑问,
    为什么用override不能触发?另外,当Adapter.Fill(DataTable)的时候
    在批量填充数据的时候,有没有想应的DataTable事件触发?
      

  9.   


    使用DBDataAdaper的Fill填充DataTable时,它是调用内部重载的、internal的NewRow方法来添加行的,不是开放public的那个NewRow方法。这不会触发事件。如果想触发事件,可以自己调用ado.net的查询方法,然后遍历DbDataReader的行来手动填充到DataTable中。
      

  10.   

    看一下DataTable的源代码public DataRow NewRow()
    {
        DataRow row = this.NewRow(-1);
        this.NewRowCreated(row);
        return row;
    }private void NewRowCreated(DataRow row)
    {
        if (this.onTableNewRowDelegate != null)
        {
            DataTableNewRowEventArgs e = new DataTableNewRowEventArgs(row);
            this.OnTableNewRow(e);
        }
    }
    public(公开)的NewRow方法做两件事,其实就是首先调用internal(不公开)的NewRow方法添加一条记录,然后触发事件。
      

  11.   

    反射出来的OnTableNewRow代码protected virtual void OnTableNewRow(DataTableNewRowEventArgs e)
    {
        //onTableNewRowDelegate是event TableNewRow编译后产生的私有委托
         if (this.onTableNewRowDelegate != null)
        {
            Bid.Trace("<ds.DataTable.OnTableNewRow|INFO> %d#\n", this.ObjectID);
            this.onTableNewRowDelegate(this, e);
        }
    }从上面可以看出,当TableNewRow事件被注册过后,才会调用上述方法,你得先在构造函数中注册一下,然后NewRow()的时候便可以进到上面的方法里头,所以对于DRow的处理最好放在OnTableNewRow中去,构造函数中通常只给字段或者属性赋个初值