none
DataTable绑定在TextBox之后不会随之改变RowState? RRS feed

  • 问题

  •  

    下面这段代码能够更改DataTable的RowState:

    Code Snippet

    namespace ConsoleApplication2
    {
        class Program
        {
            public static void Main(string[] args)
            {
                //Run a function to create a DataTable with one column.
                DataTable table = MakeTable();
                DataRow row;

                // Create a new DataRow.
                row = table.NewRow();
                // Detached row.
                Console.WriteLine("New Row " + row.RowState);

                table.Rows.Add(row);
                // New row.
                Console.WriteLine("AddRow " + row.RowState);

                table.AcceptChanges();
                // Unchanged row.
                Console.WriteLine("AcceptChanges " + row.RowState);

                row["FirstName"] = "Scott";
                // Modified row.
                Console.WriteLine("Modified " + row.RowState);

                row.Delete();
                // Deleted row.
                Console.WriteLine("Deleted " + row.RowState);
            }

            public static DataTable MakeTable()
            {
                // Make a simple table with one column.
                DataTable table = new DataTable("table");
                DataColumn fnameColumn = new DataColumn(
                    "FirstName", Type.GetType("System.String"));
                table.Columns.Add(fnameColumn);
                return table;
            }
        }
    }

     

     

    但当我使用相同的办法,在Form里把DataTable绑定在TextBox却改变不了RowState,代码如下:

    Code Snippet

    namespace WindowsFormsApplication3
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            SqlConnection c1;
            SqlDataAdapter da;
            DataTable orders;

            private void button1_Click(object sender, EventArgs e)
            {
                da.Update(orders);
               
                c1.Close();
            }

            private void button3_Click(object sender, EventArgs e)
            {
                c1 = new SqlConnection("server=.;database=dbscm;uid=sa;pwd=sadb");
               
                da = new SqlDataAdapter("select * from tb_ltd_info", c1);
                SqlCommandBuilder cb = new SqlCommandBuilder(da);

                c1.Open();

                orders = new DataTable();
                da.Fill(orders);

                this.textBox1.DataBindings.Add("text", orders, "Ltd_Name", false, DataSourceUpdateMode.OnPropertyChanged);
                this.textBox2.DataBindings.Add("text", orders, "Ltd_Add", false, DataSourceUpdateMode.OnPropertyChanged);
                this.textBox3.DataBindings.Add("text", orders, "Ltd_Phone", false, DataSourceUpdateMode.OnPropertyChanged);
                this.textBox4.DataBindings.Add("text", orders, "Ltd_Fax", false, DataSourceUpdateMode.OnPropertyChanged);
                this.textBox5.DataBindings.Add("text", orders, "Ltd_EMail", false, DataSourceUpdateMode.OnPropertyChanged);
               
            }
        }
    }

     

     

    我现在必须要手动在da.Update(orders);前插入以下代码才可以更新:

    Code Snippet

                foreach (DataRow Row in orders.Rows)
                    Row.EndEdit();

     

     

    这是什么原因?并且我担心采用历遍的方式提交更改状态会产生效率问题,不知道要怎么处理?
    2008年12月8日 8:52

答案

  •  

    DataRow里面有四个版本: Current, Default和Original,还有Proposed,各个值的意思,建议你去MSDN查看DataRowVersion的说明。当你TextBox的绑定到DataRow上面的时候,TextBox是通过DataRow.BeginEdit,DataRow.EndEdit和DataRow.CancelEdit来编辑DataRow各个列的值得。

     

    一般顺序是这样的:

    1. 你在TextBox里面把值修改了,这是TextBox调用DataRow.BeginEdit,并且把当前那一行的Version设置为Proposed。
    2. 你在TextBox里面按回车,表示提交修改,TextBox调用DataRow.EndEdit来确认你的更改。但是在调用AcceptChanges之前,DataSet并没有实际接受你的更改。
    3. 如果你在TextBox里面按ESC键,表示取消当前修改,TextBox调用DataRow.CancelEdit来取消更改。

    根据http://msdn.microsoft.com/en-us/library/ch2aw0w6.aspx里面的说明,你可以通过注册DataTable.ColumnChanged事件来获取到更新,这个事件处理函数中你应该调用EndEdit来确认更改。

    2008年12月8日 14:42
  •  yuzifu 写:
     Killmyday 写:

     

    DataRow里面有四个版本: Current, Default和Original,还有Proposed,各个值的意思,建议你去MSDN查看DataRowVersion的说明。当你TextBox的绑定到DataRow上面的时候,TextBox是通过DataRow.BeginEdit,DataRow.EndEdit和DataRow.CancelEdit来编辑DataRow各个列的值得。

     

    一般顺序是这样的:

    1. 你在TextBox里面把值修改了,这是TextBox调用DataRow.BeginEdit,并且把当前那一行的Version设置为Proposed。
    2. 你在TextBox里面按回车,表示提交修改,TextBox调用DataRow.EndEdit来确认你的更改。但是在调用AcceptChanges之前,DataSet并没有实际接受你的更改。
    3. 如果你在TextBox里面按ESC键,表示取消当前修改,TextBox调用DataRow.CancelEdit来取消更改。

    根据http://msdn.microsoft.com/en-us/library/ch2aw0w6.aspx里面的说明,你可以通过注册DataTable.ColumnChanged事件来获取到更新,这个事件处理函数中你应该调用EndEdit来确认更改。

     

    非常感谢Killmyday的解说!困绕我的问题终于知道了。

     

    但对于你所说“但是在调用AcceptChanges之前,DataSet并没有实际接受你的更改。”,我测试的结果不一样,我在da.Update()之前显示了记录的值,发现DataTable的记录已经是更改后的值了,且行状态为unchanged,在经过DataRow.EndEdit()之后,行状态才改变为Modified

     

    的确  EndEdit()之前  

    row是一个被修改了但是不被标记为修改的可回滚版本,原来的值被存放到orignalvalue。 

    不标记是防止别的线程更新

     

    这是因为绑定后修改途中可能要进行数据验证等需求决定的,

    cancelEdit会直接取消修改

    2008年12月9日 1:33

全部回复

  •  

    DataRow里面有四个版本: Current, Default和Original,还有Proposed,各个值的意思,建议你去MSDN查看DataRowVersion的说明。当你TextBox的绑定到DataRow上面的时候,TextBox是通过DataRow.BeginEdit,DataRow.EndEdit和DataRow.CancelEdit来编辑DataRow各个列的值得。

     

    一般顺序是这样的:

    1. 你在TextBox里面把值修改了,这是TextBox调用DataRow.BeginEdit,并且把当前那一行的Version设置为Proposed。
    2. 你在TextBox里面按回车,表示提交修改,TextBox调用DataRow.EndEdit来确认你的更改。但是在调用AcceptChanges之前,DataSet并没有实际接受你的更改。
    3. 如果你在TextBox里面按ESC键,表示取消当前修改,TextBox调用DataRow.CancelEdit来取消更改。

    根据http://msdn.microsoft.com/en-us/library/ch2aw0w6.aspx里面的说明,你可以通过注册DataTable.ColumnChanged事件来获取到更新,这个事件处理函数中你应该调用EndEdit来确认更改。

    2008年12月8日 14:42
  •  Killmyday 写:

     

    DataRow里面有四个版本: Current, Default和Original,还有Proposed,各个值的意思,建议你去MSDN查看DataRowVersion的说明。当你TextBox的绑定到DataRow上面的时候,TextBox是通过DataRow.BeginEdit,DataRow.EndEdit和DataRow.CancelEdit来编辑DataRow各个列的值得。

     

    一般顺序是这样的:

    1. 你在TextBox里面把值修改了,这是TextBox调用DataRow.BeginEdit,并且把当前那一行的Version设置为Proposed。
    2. 你在TextBox里面按回车,表示提交修改,TextBox调用DataRow.EndEdit来确认你的更改。但是在调用AcceptChanges之前,DataSet并没有实际接受你的更改。
    3. 如果你在TextBox里面按ESC键,表示取消当前修改,TextBox调用DataRow.CancelEdit来取消更改。

    根据http://msdn.microsoft.com/en-us/library/ch2aw0w6.aspx里面的说明,你可以通过注册DataTable.ColumnChanged事件来获取到更新,这个事件处理函数中你应该调用EndEdit来确认更改。

     

    非常感谢Killmyday的解说!困绕我的问题终于知道了。

     

    但对于你所说“但是在调用AcceptChanges之前,DataSet并没有实际接受你的更改。”,我测试的结果不一样,我在da.Update()之前显示了记录的值,发现DataTable的记录已经是更改后的值了,且行状态为unchanged,在经过DataRow.EndEdit()之后,行状态才改变为Modified

    2008年12月9日 1:23
  •  yuzifu 写:
     Killmyday 写:

     

    DataRow里面有四个版本: Current, Default和Original,还有Proposed,各个值的意思,建议你去MSDN查看DataRowVersion的说明。当你TextBox的绑定到DataRow上面的时候,TextBox是通过DataRow.BeginEdit,DataRow.EndEdit和DataRow.CancelEdit来编辑DataRow各个列的值得。

     

    一般顺序是这样的:

    1. 你在TextBox里面把值修改了,这是TextBox调用DataRow.BeginEdit,并且把当前那一行的Version设置为Proposed。
    2. 你在TextBox里面按回车,表示提交修改,TextBox调用DataRow.EndEdit来确认你的更改。但是在调用AcceptChanges之前,DataSet并没有实际接受你的更改。
    3. 如果你在TextBox里面按ESC键,表示取消当前修改,TextBox调用DataRow.CancelEdit来取消更改。

    根据http://msdn.microsoft.com/en-us/library/ch2aw0w6.aspx里面的说明,你可以通过注册DataTable.ColumnChanged事件来获取到更新,这个事件处理函数中你应该调用EndEdit来确认更改。

     

    非常感谢Killmyday的解说!困绕我的问题终于知道了。

     

    但对于你所说“但是在调用AcceptChanges之前,DataSet并没有实际接受你的更改。”,我测试的结果不一样,我在da.Update()之前显示了记录的值,发现DataTable的记录已经是更改后的值了,且行状态为unchanged,在经过DataRow.EndEdit()之后,行状态才改变为Modified

     

    的确  EndEdit()之前  

    row是一个被修改了但是不被标记为修改的可回滚版本,原来的值被存放到orignalvalue。 

    不标记是防止别的线程更新

     

    这是因为绑定后修改途中可能要进行数据验证等需求决定的,

    cancelEdit会直接取消修改

    2008年12月9日 1:33
  •  韦恩卑鄙 写:

    的确  EndEdit()之前  

    row是一个被修改了但是不被标记为修改的可回滚版本,原来的值被存放到orignalvalue。 

    不标记是防止别的线程更新

     

    这是因为绑定后修改途中可能要进行数据验证等需求决定的,

    cancelEdit会直接取消修改

     

    感谢ing... 这个问题全明白了。

    2008年12月9日 2:04