首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

22.1.2  数据源

DataGrid是一种显示数据的非常灵活的方式。在除了调用SetDataBinding()方法时参数可以是DataSet和要显示的表名,此外,还可以将下述任何一个数据源作为参数调用该方法:

       数组(网格可以绑定到任何一个一维数组上)

       DataTable

       DataView

       DataSetDataViewManager

       实现IListSource接口的组件

       实现IList接口的组件

下面几节将给出这些数据源的示例。

1. 显示数组中的数据

这初看起来非常简单,创建一个数组,填充一些数据,再在DataGrid控件上调用SetDataSource (array,null)。下面是一些示例代码:

string[] stuff = new string[] {"One", "Two", "Three"};

dataGrid.SetDataBinding(stuff, null);

SetDataBinding带有两个参数,第一个参数是数据源,在本例中就是数组,第二个参数是null,除非数据源是一个DataSet DataViewManager类,此时这个参数应是要显示的表名。

可以用这个数组代码替换上面示例中的retrieveButton_Click事件处理程序,这段代码的结果如图22-2所示。

  22-2

可以看出,网格显示出了数组中定义的字符串的长度,而不是这些字符串。原因是在把数组用作DataGrid的数据源时,网格会查找数组中对象的第一个公共属性,并显示这个值,而不会显示字符串。字符串的第一个(也是惟一的)公共属性是其长度,所以就显示这个长度值。

解决这个问题的一种方法是为字符串创建一个包装类,如下所示:

protected class Item

{

   public Item(string text)

   {

      _text = text;

   }

   public string Text

   {

      get{return _text;}

   }

   private string _text;

}

在数据源数组代码中添加一个Item(从进行的各种处理来讲,它也可以是一个结构)的数组后,结果如图22-3所示。

  22-3

2. DataTable

DataGrid控件中显示DataTable有两种方式:

       如果DataTable是独立的,就调用SetDataBinding(DataTable, null)

       如果在DataSet中包含DataTable,就调用SetDataBinding(DataSet, "<Table Name>")

22-4所示为运行DatasourceDataTable示例代码的结果。

  22-4

注意最后一列显示了一个复选框,而不是更常见的编辑控件。DataGrid没有显示其他信息,而是从数据源中读取模式(在本例中是Products),确定在该列中应显示什么控件。但不要太激动,目前支持的类型只有两种:文本框和复选框。其他类型的映射必须手工处理。

在修改了DataGrid中的字段时,数据库中的数据不会改变,因为此时数据仅存储在本地计算机上—— 没有与数据库的活动连接。后面的“更新数据源”一节将更新原始数据。

3. 显示DataView中的数据

DataView提供了一种过滤和排序DataTable中数据的一种方式。在从数据库中选择数据时,用户一般可以单击列标题,对数据排序。此外,还可以只过滤要显示在某些行中的数据,例如用户修改过的所有数据。DataView允许限制要显示给用户的数据行,但不允许限制DataTable中的数据列。

提示:

DataView不允许修改要显示的数据列,只允许修改要显示的数据行。

本章后面的“DataGridTableStyleDataGridColumnStyle”一节将介绍一个示例,说明如何限制要显示的数据列。

根据现有的DataTable创建DataView的代码如下所示:

DataView dv = new DataView(dataTable);

创建好后,就可以改变DataView上的设置,当该视图显示在DataGrid中时,这些设置会影响要显示的数据,以及允许对这些数据进行的操作。例如:

       设置 AllowEdit = false表示在数据行上禁用所有列的编辑功能。

       设置AllowNew = false 表示禁用新行功能。

       设置 AllowDelete = false表示禁用删除行的功能。

       设置 RowStateFilter只显示指定状态的行。

       设置 RowFilter 可过滤数据行。

       按照给定的列排序

下一节将介绍使用RowStateFilter设置,其他选项都是可以自我解释的。

(1) 通过数据过滤数据行

创建好DataView后,就可以通过设置RowFilter属性,来改变视图中的数据。这个属性是一个字符串,可用作按照给定条件过滤数据的一种方式——  该字符串的值就是过滤条件。其语法类似于一般SQL中的WHERE子句,但主要是对已经从数据库中选择出来的数据进行操作。

过滤子句的一些示例如表22-1所示。

  22-1

 

 

UnitsInStock > 50

只显示UnitsInStock列大于50的行

Client = 'Smith'

只返回给定客户的记录

County LIKE 'C*'

返回County字段以C开头的所有记录——  例如返回Cornwall CumbriaCheshire Cambridgeshire所在的行,可以使用%表示匹配一个字符的通配符,而*表示匹配0个或多个字符的通配符

 

运行环境尽可能在过滤表达式中使用与源列相匹配的数据类型。例如,在前面的示例中,使用UnitsInStock > '50'表达式就是合法的,尽管该列是一个整数列。但如果提供了一个无效的过滤字符串,就会产生EvaluateException

(2) 根据状态过滤数据行

DataView中的每一行都有一个定义好的行状态,它们的值如表22-2所示,这些状态也可以用于过滤用户查看的行。

  22-2

DataViewRowState

   

Added

新创建的所有行

CurrentRows

除了被删除的行以外的其他行

Deleted

最初被选中,且已经删除的行——  不显示已经删除的新建行

                                                          (续表)  

DataViewRowState

   

ModifiedCurrent

列出所有已被修改的行,并显示这些行的当前值

ModifiedOriginal

列出所有已被修改的行,但显示这些行的初值,而不是当前值

OriginalRows

最初从数据源中选中的所有行,不包括新行。显示列的初值(即如果进行了修改,不显示当前值)

Unchanged

没有修改的行

 

22-5显示了两个网格,一个网格显示已添加、删除或修改的数据行,另一个网格显示状态为上表中一种的行。

  22-5

过滤器不仅可以用于可视化的行,还可以用于这些行中列的状态。在进行ModifiedOriginal ModifiedCurrent选择时,这是很明显的。这两个状态都在第21章介绍过了,它们都是基于DataRowVersion枚举的。例如,如果用户更新了数据行中的一列,该行就会在选择ModifiedOriginal ModifiedCurrent时显示出来,但其实际值可以是从数据库中选择出来的初值(如果选择了ModifiedOriginal),或者DataColumn中的当前值(如果选择了ModifiedCurrent)

(3) 对数据行进行排序

除了过滤数据外,有时还需要对DataView中的数据进行排序。可以在DataGrid控件中单击列标题,这会按照升序或降序的顺序对该列进行排序,如图22-6所示。惟一的问题是控件只能对一列进行排序,而底层的DataView可以对多个列进行排序。

在对数据列进行排序时,可以单击列的标题(例如上面的ProductName),也可以通过代码排序,DataGrid会显示一个箭头位图,表示对哪一列进行排序。

  22-6

要编程设置列的排列顺序,可以使用DataViewSort属性:

dataView.Sort = "ProductName";

dataView.Sort = "ProductName ASC, ProductID DESC";

上面的第一行按照ProductName列对数据排序,如图22-6所示。第二行按照ProductName列对数据进行升序排序,再以ProductID的降序来排序。

DataView支持对列进行升序或降序排序——  默认为升序。如果选择对DataView中的多个列进行排序,DataGrid就不会显示任何排序箭头。

网格中的每一列都是强类型化的,其排序顺序不是基于列的字符串表示,而是基于实际的数据。如果DataGrid有一个日期列,要对它进行排序,网格就会按日期来进行排序,而不是按日期字符串来进行排序。

4. 显示DataSet类中的数据

DataGrid主要用于显示DataSet中的数据。和以前的示例一样,DataGrid一次只能显示一个DataTable,但在下面的示例DataSourceDataSet中,可以浏览DataSet中的关系。下面的代码可以根据Northwind数据库中的CustomersOrders表生成这样一个DataTable。这个示例从两个DataTable中加载数据,然后在这些表之间创建了一个关系CustomerOrders

string source ="server=(local)\\NetSDK;" +

            "uid=QSUser;pwd=QSPassword;" +

            "database=northwind";

string orders = "SELECT * FROM Orders";

string customers = "SELECT * FROM Customers";

SqlConnection conn = new SqlConnection(source);

SqlDataAdapter da = new SqlDataAdapter(orders, conn);

DataSet ds = new DataSet();

da.Fill(ds, "Orders");

da = new SqlDataAdapter(customers , conn);

da.Fill(ds, "Customers");

ds.Relations.Add("CustomerOrders",

               ds.Tables["Customers"].Columns["CustomerID"],

               ds.Tables["Orders"].Columns["CustomerID"]);

创建好后,通过调用SetDataBinding,就可以把DataSet绑定到DataGrid上:

dataGrid1.SetDataBinding(ds, "Customers");

这样会得到如22-7所示的屏幕图。

  22-7

注意,与本章前面的DataGrid不同,每个记录的左边都有一个+号,这表示DataSetcustomers orders表之间有一个可导航的关系。在代码中可以定义许多这类关系。

单击+号,就会显示关系列表(如果关系已经显示出来,单击+号就会隐藏该关系)。单击关系名,就可以定位到链接的记录上,如图22-8所示,在本例中是列出选中客户的所有订单。

  22-8

DataGrid控件的右上角还包含两个新图标。箭头允许用户可以导航回父行,显示上一页的内容。标题行显示父记录的细节,单击另一个按钮会隐藏或显示该箭头。

DataViewManager中显示数据

DataViewManager中显示的数据与DataSet中显示的数据相同,但在为DataSet创建DataViewManager时,会为每个DataTable创建一个单独的 DataView,根据过滤条件或者行的状态改变显示出来的行,如上面的DataView示例所示。即使不希望过滤数据,也可以把DataSet包装到 DataViewManager中,以进行显示,因为这样在修改源代码时可以使用更多的选项。

下面的示例根据上一例中的DataSet 创建一个DataViewManager,然后改变Customers表中的DataView,使之只显示来自英国的客户:

DataViewManager dvm = new DataViewManager(ds);

dvm.DataViewSettings["Customers"].RowFilter = "Country='UK'";

dataGrid.SetDataBinding(dvm, "Customers");

如图22-9所示为DataSourceDataViewManager例代码的运行结果。

  22-9

5. IListSource IList接口

DataGrid还支持执行IListSourceIList接口之一的所有对象。IListSource只有一个方法GetList(),它返回一个IList接口,而IList比较有趣,它可由运行库中的许多类执行,执行这个接口的类有ArrayArrayListStringCollection

在使用IList时,对前面Array的警告也适用于集合中的对象—— 如果使用StringCollection作为DataGrid的数据源,网格中就会显示字符串的长度,而不是我们希望显示的元素文本。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论