三、DataGrid
这里说的DataGrid是winform中的DataGrid,一般都是跟DataView绑定来显示DataTable中的数据,和修改DataTable中的数据。
DotNet的DataGrid的功能强大,可是在使用上与以前的习惯不太一样,有时还比较麻烦,所以很多人都对这个DataGrid感到有些摸不着头脑,有一种无从下手的感觉,其实把一些概念搞清楚了许多问题就会迎刃而解了。
DataGrid通过DataSource和DataMember 属性来绑定其要显示的数据源。数据源一般是DataTable、DataView、DataSet等,不过将这些数据源绑定到DataGrid时实际上是绑定的DataView。若数据源是DataTable时,实际上是绑定了此DataTable的DefaultView,若数据源是DataSet时,则可以向DataMember属性设置一个字符串,该字符串指定要绑定到的表,然后再将DataMember指定的那个DataTable的DefaultView绑定到DataGrid。
所以DataGrid实际显示的是DataTable经过筛选的DataView。
◆ DataGrid以何种方式显示DataView的数据
DataGrid绑定到一个DataView后,由DataGrid.TableStyles中的DataGridTableStyle 对象的集合来控制这个DataView的哪些列要显示,列的宽度多少,列标头的文本是什么等等。确省的DataGrid.TableStyles中不包含任何对象,这时DataGrid将会按照DataView列的顺序将所有的列都显示出来。一般应用中都会设置TableStyles来控制显示的内容及格式。
例如DataGrid绑定到一张叫order的DataTable,这个DataTable包含了OrderID、CustomerID、OrderDate、ShipName、ShipAddress等字段,可以看到DataGrid将会按照DataView列的顺序将所有的列都显示出来
我们只想显示OrderID、CustomerID、OrderDate这三个字段,并且想将OrderID的列表头显示为“订单号”,CustomerID显示为“客户号”,OrderDate显示为“订单日期”,这就要用TableStyles来控制了。
新建一个TableStyle,将此TableStyle.MappingName属性对应到这个TableStyle要控制的那个DataTable的名字:
DataGridTableStyle myTableStyle = new DataGridTableStyle();
myTableStyle.MappingName = "myDateTable";
再建立三个DataGridColumnStyle,分别用来控制将要显示的三个列:
DataGridColumnStyle myColumnStyle1 = new DataGridTextBoxColumn(); myColumnStyle1.MappingName = "OrderID"; myColumnStyle1.HeaderText = "订单号"; DataGridColumnStyle myColumnStyle2 = new DataGridTextBoxColumn(); myColumnStyle2.MappingName = "CustomerID"; myColumnStyle2.HeaderText = "客户号"; DataGridColumnStyle myColumnStyle3 = new DataGridTextBoxColumn(); myColumnStyle3.MappingName = "OrderDate"; myColumnStyle3.HeaderText = "订单日期"; 将这三个DataGridColumnStyle添加到TableStyle中: myTableStyle.GridColumnStyles.Add(myColumnStyle1); myTableStyle.GridColumnStyles.Add(myColumnStyle2); myTableStyle.GridColumnStyles.Add(myColumnStyle3);
最后将TableStyle添加到DataGrid中:
dataGrid1.TableStyles.Add(myTableStyle);
将TableStyle添加到DataGrid后,再绑定数据源。
◆ DataGrid的编辑修改
DataGrid支持对DataGrid所显示的DataTable的编辑修改,只要DataGrid的ReadOnly属性为False,就可以在DataGrid中直接修改单元中的内容,修改完后数据将直接反应到此DataGrid对应的那个DataTable的单元。
如果这个DataTable是通过vs.net的可视化数据设计器新建DataAdapter,并生成了SelectCommand、InsertCommand、UpdateCommand、DeleteCommand这四个命令,用DataAdapter的Fill方法得来的,那么事情就简单了,修改过的DataTable你可以直接用DataAdapter的UpDate方法写回到数据库。下面看一下vs.net的可视数据数据器生成的InsertCommand命令:
this.sqlInsertCommand1.CommandText = @"INSERT INTO Customers(CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax)VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle,@Address, @City, @Region, @PostalCode, @Country, @Phone, @Fax);SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region, PostalCode, Country, Phone,Fax FROM Customers WHERE (CustomerID = @CustomerID)"; this.sqlInsertCommand1.Connection = this.sqlConnection2; this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CustomerID", System.Data.SqlDbType.NVarChar, 5, "CustomerID")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CompanyName", System.Data.SqlDbType.NVarChar, 40, "CompanyName")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@ContactName", System.Data.SqlDbType.NVarChar, 30, "ContactName")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@ContactTitle", System.Data.SqlDbType.NVarChar, 30, "ContactTitle")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Address", System.Data.SqlDbType.NVarChar, 60, "Address")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@City", System.Data.SqlDbType.NVarChar, 15, "City")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Region", System.Data.SqlDbType.NVarChar, 15, "Region")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@PostalCode", System.Data.SqlDbType.NVarChar, 10, "PostalCode")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Country", System.Data.SqlDbType.NVarChar, 15, "Country")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Phone", System.Data.SqlDbType.NVarChar, 24, "Phone")); this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Fax", System.Data.SqlDbType.NVarChar, 24, "Fax"));
DataAdapter的SelectCommand是用来DataAdapter.Fill()方法来填充DataTable的,SelectCommand选择的数据表行集将被填充到DataTable中,然后DataGrid将它显示出来。
DataGrid在经过编辑修改后,其对应的DataTable中的行就可能出现文章上面所述的那五种状态,可能是新加的(Added),可能是修改了的(Modified),可能是删除的(Deleted),DataAdapter.UpDate()方法将通过调用InsertCommand命令将状态为Added的行插入到数据库,UpdateCommand将状态为Modified的行在数据库中做修改,DeleteCommand将状态为Deleted的行在数据库真正的删除。
如果不是通过vs.net的可视化数据设计器新建DataAdapter,没有自动生成SelectCommand、InsertCommand、UpdateCommand、DeleteCommand这四个命令,那么就可能需要自己写InsertCommand、UpdateCommand、DeleteCommand命令,有一种情况就是当SelectCommand至少返回一个主键列或唯一的列时,可以通过SqlCommandBuilder来自动根据SelectCommand命令来自动生成另外三个更新命令,例如:
SqlConnection myConn = new SqlConnection(myConnection); SqlDataAdapter myDataAdapter = new SqlDataAdapter(); myDataAdapter.SelectCommand = new SqlCommand(mySelectQuery, myConn); //建立DataAdapter的SelectCommand命令 SqlCommandBuilder custCB = new SqlCommandBuilder(myDataAdapter); //建立此DataAdapter的CommandBuilder, //这样系统就会给此DataAdapter自动生成 InsertCommand、UpdateCommand、DeleteCommand三个命令。
否则,要用DataAdapter.UpDate()方法更新数据库就要自己写InsertCommand、UpdateCommand、DeleteCommand这三个命令,可以参考上面给出的vs.net自动生成的InsertCommand命令的写法。