这两天做一个练习,将界面上的控件属性与DataTable绑定,DataTable最终保存到本地的xml;反过来,根据本地的xml可以将数据写入DataTable,然后通过绑定还原到控件上。
主要是根据Control.DataBindings.Add方法。上一篇有相关介绍。本片说说中间碰到的稀奇古怪的问题,留文提醒自己。
1. 保存xml时,将DataTable写到DataSet的Tables中时,用DataTable.Copy()无法拷贝完整的数据。
public virtual void WriteXml(DataTable dt, string path){ //... DataSet ds = new DataSet(); DataTable failed = dt.Copy();//注意:这里用Copy不会复制数据。 DataTable copy = dt.Clone(); copy.Rows.Add(dt.Rows[0].ItemArray); //...}
前面提到了,DataTable的数据是与界面上的控件绑定了的。不知道Copy失败的原因是不是在这里,有兴趣的可以深入的研究Copy的后台执行逻辑。回到正题,例如:传入的dt数据为:其中A为int,B为bool,C为bool,D为string
A B C D
2 true false ok
在上面的步骤执行完了之后,failed的值为:A-0 B-false C-false D-;也就是说返回了属性的默认值。
后来的处理方法看下面的copy。不过由于这类的DataTable都是一行数据,所以可以这么处理,如果碰到多行数据的情况,这种方法就不实用了。这里的Copy为什么复制数据失败,有待高手解答...o(∩_∩)o
第二个很纠结的地方。从xml中读取数据时,将DataSet中的相应的Table值赋予给DataTable,通过之前的绑定,直接给控件赋值。过程中,DataTable给DataTable赋值时,犯了一个错误,导致后来的绑定失败。
先看错误的代码。
public static void FromDsToDT(ref DataTable targetDt, DataTable source){ targetDt.Rows.Clear(); targetDt.Rows.Add(); foreach (DataColumn col in source.Columns) { string colName = col.ColumnName; if (targetDt.Columns.Contains(colName)) targetDt.Rows[0][colName] = source.Rows[0][colName]; } targetDt.AcceptChanges();//此步骤很重要,否则可能绑定没有实现到控件上。}
实现的思路是将源DataTable根据列名提取数据,同时将数据赋值给目标DT的相同列名的第一行。在赋值之前,对目标DT清空旧的行数据,同时添加一行。最后问题就出现在这里,清空行数据之后,使原先的部分绑定失效了。后台通过代码测试,执行了Clear和Add之后,部分控件的DataBindings[0].isBinding变成了false,从而导致最终DataTable的数据不能表现在空间上。
知道了原因,修改就非常简单了,只需要屏蔽上面的Clear和Add两行即可。
这里有一个需要注意的是:最后的一句targetDt.AcceptChanges也非常重要。如果没有这一步,对targetDt数据所做的修改可能只是一个修改标记,后台的数值还没有改过来。
【扩展代码】:两个控件的属性相互绑定。例如:有两个TextBox控件txtTo和txtFrom,将两个控件的text绑定起来。代码为
txtTo.DataBindings.Add("Text", txtFrom, "Text");
执行此行绑定之后,修改txtTo的Text属性时,txtFrom的Text属性也会改变;修改txtFrom的Text时,txtTo的Text属性也会变。
留文备用,转载请注明出处: