数据绑定控件收藏

通过前面的例子我们看到每次我们要显示数据的时候都要通过一个循环来显示满足条件的数据,这是一个比较麻烦的过程,为此微软定义了一系列的控件专门用于显示数据的格式,通过这些控件可以以可视化的方式查看绑定数据之后的效果。这些控件称之为数据绑定控件。在asp.net 中所有的数据库绑定控件都是从BaseDataBoundControl 这个抽象类派生的,这个抽象类定义了几个重要属性和一个重要方法:
DataSource 属性:指定数据绑定控件的数据来源,显示的时候程序将会从这个数据源中获取数据并显示。
DataSourceID 属性:指定数据绑定控件的数据源控件的ID, 显示的时候程序将会根据这个ID 找到相应的数据源控件,并利用这个数据源控件中指定方法获取数据并显示。
DataBind() 方法:当指定了数据绑定控件的DataSource 属性或者DataSourceID 属性之后,再调用DataBind() 方法才会显示绑定的数据。并且在使用数据源时,会首先尝试使用DataSourceID 属性标识的数据源,如果没有设置DataSourceID 时才会用到DataSource 属性标识的数据源。也就是说DataSource 和DataSourceID 两个属性不能同时使用
数据绑定控件的DataSource 控件属性必须是一个可以枚举的数据源,如实现了ICollection 、IEnumerable 或IListSource 接口的类的实例。

今天要讲述的内容有:
DropDownList 控件
ListBox 控件
GridView 控件
DataList 控件
Repeater 控件

FormView 控件

DetailsView 控件
DropDownList 控件
DropDownList 控件是一个相对比较简单的数据绑定控件,它在客户端被解释成<select></select> 这样的HTML 标记,也就是只能有一个选项处于选中状态。
DropDownList 控件常见属性:
AutoPostBack 属性:这个属性的用法在讲述基本控件的时候已经讲过,是用来设置当下拉列表项发生变化时是否主动向服务器提交整个表单,默认是false ,即不主动提交。如果设置为true ,就可以编写它的SelectedIndexChanged 事件处理代码进行相关处理(注意:如果此属性为false 即使编写了SelectedIndexChanged 事件处理代码也不会马上起作用)。
DataTextField 属性:设置列表项的可见部分的文字。
DataValueField 属性:设置列表项的值部分。
Items 属性:获取控件的列表项的集合。
SelectedIndex 属性:获取或设置 DropDownList 控件中的选定项的索引。
SelectedItem 属性:获取列表控件中索引最小的选定项。
SelectedValue 属性:取列表控件中选定项的值,或选择列表控件中包含指定值的项。

因为在实际开发中,用户希望直观地看见选中哪个选项,而在操作数据库的时候我们更希望直接以该值对应的编号来操作,利用DataTextField 属性和DataValueField 属性就可以很方便地做到这一点,这两个属性通常是数据源中的某个字段名(如果DataSource 属性是DataTable 或者是DataView 的话)或者范型集合中实体的属性(如果DataSource 属性是System.Collections.Generic.List<T> 的话,则可以指定为T 的属性)。
下面是DropDownList 控件的例子,依然用到的是第六章中创建的表(本代码采用了单页模式):

复制代码

1.	<%@ Page Language="C#" %> 
2.	<%@ Import Namespace="System.Data" %> 
3.	<%@ Import Namespace="System.Data.SqlClient" %> 
4.	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
5.	
6.	<script runat="server"> 
7.	
8.	    protected void Page_Load(object sender, EventArgs e) 
9.	    { 
10.	        if (!Page.IsPostBack) 
11.	        { 
12.	            BindMonthList(); 
13.	            BindUserList(); 
14.	        } 
15.	    } 
16.	
17.	    private void BindMonthList() 
18.	    { 
19.	        //因为所有的数组都是Array类的派生类 
20.	        //而Array类实现了IEnumerable和ICollection这两个接口,所以可以被当作数据源 
21.	        int[] monthList = new int[12]; 
22.	        for (int i = 0; i <= 11; i++) 
23.	        { 
24.	            monthList[i] = i + 1; 
25.	        } 
26.	        ddlMonthList.DataSource = monthList; 
27.	        ddlMonthList.DataBind();//注意不能缺少这一句,否则下拉列表中没有数据 
28.	    } 
29.	
30.	    private void BindUserList() 
31.	    { 
32.	        //实例化Connection对象 
33.	        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
34.	        //实例化Command对象 
35.	        SqlCommand command = new SqlCommand("select UserID,RealName from UserInfo", connection); 
36.	        SqlDataAdapter adapter = new SqlDataAdapter(command); 
37.	        DataTable data = new DataTable(); 
38.	        adapter.Fill(data); 
39.	
40.	        ddlUserList.DataTextField = "RealName";//指定下拉列表中的文字显示部分 
41.	        ddlUserList.DataValueField = "UserID";//指定下拉列表中的值部分 
42.	        ddlUserList.DataSource = data; 
43.	        ddlUserList.DataBind(); 
44.	    } 
45.	</script> 
46.	
47.	<html  > 
48.	<head runat="server"> 
49.	    <title>DropDownList控件的例子</title> 
50.	</head> 
51.	<body> 
52.	    <form id="form1" runat="server"> 
53.	    <div> 
54.	        <asp:DropDownList ID="ddlMonthList" runat="server"> 
55.	        </asp:DropDownList> 
56.	        <asp:DropDownList ID="ddlUserList" runat="server"> 
57.	        </asp:DropDownList></div> 
58.	    </form> 
59.	</body> 
60.	</html>

下面是运行效果:

注意,第二个DropDownList 控件绑定数据源时有两句话必不可少,就是:

复制代码

1.	ddlUserList.DataTextField = "RealName";//指定下拉列表中的文字显示部分 
2.	ddlUserList.DataValueField = "UserID";//指定下拉列表中的值部分

如果缺少这两句,将会是下面的效果:

另外,DropDownList 控件默认情况下是第一个选项处于选中状态,如果我们想在绑定数据之后让某个选项处于选中状态,可以利用它的Items 属性,DropDownList 控件的Items 属性其实是一个ListItemCollection 的实例,ListItemCollection 类有两个重要方法:

public ListItem FindByText (string text) :在选项集合中查找指定文字的选项。

public ListItem FindByValue (string value) :在选项集合中查找指定值的选项。

利用这个属性,我们可以让某个选项在数据绑定后就处于选中状态。比如在上面的代码中我们希望绑定数据源后,让刘备处于选中状态,那么我们的BindUserList() 的代码可以这么写:

复制代码

1.	private void BindUserList() 
2.	    { 
3.	        //实例化Connection对象 
4.	        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
5.	        //实例化Command对象 
6.	        SqlCommand command = new SqlCommand("select UserID,RealName from UserInfo", connection); 
7.	        SqlDataAdapter adapter = new SqlDataAdapter(command); 
8.	        DataTable data = new DataTable(); 
9.	        adapter.Fill(data); 
10.	
11.	        ddlUserList.DataTextField = "RealName";//指定下拉列表中的文字显示部分 
12.	        ddlUserList.DataValueField = "UserID";//指定下拉列表中的值部分 
13.	        //DataTable类实现了IListSource接口 
14.	        ddlUserList.DataSource = data; 
15.	        ddlUserList.DataBind(); 
16.	        //根据指定文字找到了对应的选项 
17.	        ListItem item = ddlUserList.Items.FindByText("刘备"); 
18.	        //如果该选项不为null,则让该选项处于选中状态 
19.	        //如果不进行这个判断,而选项集合中没有对应的选项,则会抛出异常 
20.	        if (item != null) 
21.	        { 
22.	            item.Selected = true; 
23.	        } 
24.	    }

下面是修改后的代码的运行结果:

ListBox 控件

ListBox 控件和DropDownList 控件非常类似,ListBox 控件是也是提供一组选项供用户选择的,只不过DropDownList 控件只能有一个选项处于选中状态,并且每次只能显示一行(一个选项),而ListBox 控件可以设置为允许多选,并且还可以设置为显示多行。

除了与DropDownList 具有很多相似的属性之外,ListBox 控件还有以下属性:

Rows 属性:设置ListBox 控件显示的行数。

SelectionMode 属性:设置ListBox 的选择模式,这是一个枚举值,它有Multiple 和Single 两个值,分别代表多选和单选,默认是Single ,即同时只能有一个选项处于选中状态。如果要想实现多选,除了设置SelectionMode 属性为Multiple 外,在选择时需要按住Ctrl 键。

需要说明的是,因为ListBox 允许多选,所以如果ListBox 的SelectionMode 属性为Multiple ,那么SelectedIndex 属性指的是被选中的选项中索引最小的那一个,SelectedValue 属性指的是被选中的选项集合中索引最小的那一个的值。

下面是ListBox 的用法举例:

复制代码

1.	<%@ Page Language="C#" %> 
2.	<%@ Import Namespace="System.Data" %> 
3.	<%@ Import Namespace="System.Data.SqlClient" %> 
4.	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
5.	
6.	<script runat="server"> 
7.	
8.	    protected void Page_Load(object sender, EventArgs e) 
9.	    { 
10.	        if (!Page.IsPostBack) 
11.	        { 
12.	            BindUserList(); 
13.	        } 
14.	    } 
15.	
16.	    private void BindUserList() 
17.	    { 
18.	        //实例化Connection对象 
19.	        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
20.	        //实例化Command对象 
21.	        SqlCommand command = new SqlCommand("select UserID,RealName from UserInfo", connection); 
22.	        SqlDataAdapter adapter = new SqlDataAdapter(command); 
23.	        DataTable data = new DataTable(); 
24.	        adapter.Fill(data); 
25.	
26.	        listUsers.DataTextField = "RealName";//指定下拉列表中的文字显示部分 
27.	        listUsers.DataValueField = "UserID";//指定下拉列表中的值部分 
28.	        //DataTable类实现了IListSource接口 
29.	        listUsers.DataSource = data; 
30.	        listUsers.DataBind(); 
31.	    } 
32.	
33.	    protected void btnOK_Click(object sender, EventArgs e) 
34.	    { 
35.	        string selectedUserName = string.Empty; 
36.	        //遍历ListBox中的每一个选项 
37.	        foreach (ListItem item in listUsers.Items) 
38.	        { 
39.	            //如果选项被选中 
40.	            if (item.Selected) 
41.	            { 
42.	                selectedUserName += item.Value+","; 
43.	            } 
44.	        } 
45.	        //如果至少有一个选项处于选中状态 
46.	        if (!string.IsNullOrEmpty(selectedUserName)) 
47.	        { 
48.	            //删除最后一个","符号 
49.	            selectedUserNameselectedUserName = selectedUserName.Remove(selectedUserName.Length - 1); 
50.	        } 
51.	        Response.Write("您选择的用户编号有:" + selectedUserName); 
52.	    } 
53.	</script> 
54.	
55.	<html  > 
56.	<head runat="server"> 
57.	    <title>ListBox控件用法的例子</title> 
58.	</head> 
59.	<body> 
60.	    <form id="form1" runat="server"> 
61.	    <div> 
62.	        <asp:ListBox ID="listUsers" runat="server" SelectionMode="Multiple"></asp:ListBox> 
63.	        <asp:Button ID="btnOK" runat="server" OnClick="btnOK_Click" Text="确定" /></div> 
64.	    </form> 
65.	</body> 
66.	</html>

下面是运行情况:

按住Ctrl 键同时选择几个选项,然后点击“确定”按钮之后的结果:

GridView 控件

GridView 控件作为asp.net1.1 下的DataGrid 的替代品,它内置了表格呈现样式。GridView 控件用来在表中显示数据源的值。每列表示一个字段,而每行表示一条记录。GridView 控件支持下面的功能:

绑定至数据源控件,如 SqlDataSource 。

内置排序功能。

内置更新和删除功能。

内置分页功能。

内置行选择功能。

以编程方式访问 GridView 对象模型以动态设置属性、处理事件等。

多个键字段。

用于超链接列的多个数据字段。

可通过主题和样式进行自定义的外观。

可以实现多种样式的数据展示。

GridView 控件主要有以下常见属性:

AllowPaging 属性:设置是否启用分页功能。

AllowSorting 属性:设置是否启用排序功能。

AutoGenerateColumns 属性:设置是否为数据源中的每个字段自动创建绑定字段。这个属性默认为true ,但在实际开发中很少会自动创建绑定列,我们总会根据一些情况让一些列不显示,比如显示用户列表的时候不会将用户密码显示出来,显示文章列表的时候不会将文章内容显示出来。

Columns 属性:获取GridView 控件中列字段的集合。

PageCount 属性:获取在GridView 控件中显示数据源记录所需的页数。

PageIndex 属性:获取或设置当前显示页的索引。

PagerSetting 属性:设置GridView 的分页样式。

PageSize 属性:设置GridView 控件每次显示的最大记录条数。

下图是将一个GridView 控件拖到页面的情况:

点击“编辑列… ”会出现下面的界面:

从上面的图中我们可以看出在GridView 中可以显示7 中类型的字段,它们分别是:

BoundField: 绑定字段,以文本的方式显示数据。

CheckBoxField: 复选框字段,如果数据库是bit 字段,则以此方式显示。

HyperLinkField: 用超级连接的形式的显示字段值。

ImageField: 用于显示存放Image 图象的url 字段数据,显示成图片效果。

ButtonField :显示按钮列。

CommandField :显示可执行操作的列,可以执行编辑或者删除等操作。可以设置它的ButtonType 属性来决定显示成普通按钮、图片按钮或者超级链接。

TemplateField: 自定义数据的显示方式,在这里我们可以使用我们所熟悉的HTML 控件或者asp.net Web 服务器控件。

对于我们经常使用到的Users 这个表,这次我们不再使用for 循环来显示了,这次使用GridView 控件来显示。GridView 控件的字段大都有HeaderText 这个属性,这个属性是用来设置数据的镖头的,如果我们不设置的话默认都是以数据库的相应字段作为表头。另外还有一个DataField 属性,这个属性是用来设置要绑定显示的数据的属性或者列名。在这里我们希望在显示的时候给出一个链接,用户可以点击这个链接跳转到查看详细介绍的页面,并且我们还希望将用户的电子邮件显示成超级链接的方式。

在这里还需要介绍一个属性:DataNavigateUrlFormatString ,类似的还有DataTextFormatString ,有时候在显示数据的时候我们并不希望仅仅将数据简简单单显示,还希望用一定的格式来显示,那么就可以设置这个属性,在显示的时候我们用到了一个HyperLinkField ,用来显示一个超级链接,它的设置如下:

复制代码

1.	<asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}" 
2.	                    DataTextField="RealName" HeaderText="查看" />

我们看到DataNavigateUrlFormatString 属性的值为"ShowUser.aspx?UserId={0}" ,而DataNavigateUrlFields 属性的值为"UserId" ,也就是将来显示每行数据的时候都会将该行对应的“UserId ”字段的值替换{0} ,类似于string.Format("ShowUser.aspx?UserId={0}" ,[“UserId”] 的值) 。

对于电子邮件的显示,我们发现BoundField 、CheckBoxField 、HyperLinkField 、ImageField 和ButtonField 及CommandField 字段都较难实现或者根本不可能实现我们的要求,这时可以使用TemplateField 这种类型的字段。

在GridView 控件中TemplateField 字段中可以定义5 中不同类型的模版,分别如下:

AlternatingItemTemplate :交替项模版,即偶数项中显示的内容,可以进行数据绑定。

EditItemTemplate :编辑项模版,当当前这条数据处于编辑状态的时候要显示的内容,可以进行数据绑定。

FooterTemplate :脚模版,即脚注部分要显示的内容,不可以进行数据绑定。

HeaderTemplate :头模版,即表头部分要显示的内容,不可以进行数据绑定。

ItemTemplate :项模版,处于普通项中要显示的内容,如果指定了AlternatingItemTemplate 中的内容,则这里的设置是奇数项的显示效果。可以进行数据绑定。

注意:可以不设置AlternatingItemTemplate ,如果没有设置AlternatingItemTemplate ,那么所有的数据项在非编辑模式下都按照ItemTemplate 中的设置显示。

下面是用分页显示Users 表中的数据的例子,对于奇数行用户的电子邮件仅仅显示电子邮件地址,偶数行的用户显示为超级链接。以下是代码:

复制代码

1.	<%@ Page Language="C#" %> 
2.	<%@ Import Namespace="System.Data" %> 
3.	<%@ Import Namespace="System.Data.SqlClient" %> 
4.	
5.	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
6.	
7.	<script runat="server"> 
8.	
9.	    protected void Page_Load(object sender, EventArgs e) 
10.	    { 
11.	        if (!Page.IsPostBack) 
12.	        { 
13.	            //默认显示第一页,不过在GridView中第一页的页索引是0 
14.	            //注意:在C#中集合里的索引也都是以0开始 
15.	            BindGridView(0); 
16.	        } 
17.	    } 
18.	    //指定绑定页面的数据 
19.	    private void BindGridView(int pageIndex) 
20.	    { 
21.	        //实例化Connection对象 
22.	        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
23.	        //实例化Command对象 
24.	        SqlCommand command = new SqlCommand("select * from UserInfo", connection); 
25.	        SqlDataAdapter adapter = new SqlDataAdapter(command); 
26.	        DataTable data = new DataTable(); 
27.	        adapter.Fill(data); 
28.	
29.	        #region 注意这部分代码可以在设计视图中设置,不必写在代码里 
30.	        gvUserList.AllowPaging = true;//设置允许自动分页 
31.	        //gvUserList.AutoGenerateColumns = false;//设置不允许自动绑定列 
32.	        gvUserList.PageSize = 5;//设置每页显示5条记录 
33.	        #endregion 
34.	         
35.	        gvUserList.DataSource = data; 
36.	        gvUserList.PageIndex = pageIndex;//设置当前显示第几页 
37.	        gvUserList.DataBind(); 
38.	    } 
39.	
40.	    //翻页事件 
41.	    protected void gvUserList_PageIndexChanging(object sender, GridViewPageEventArgs e) 
42.	    { 
43.	        //指定新页面,重新绑定数据 
44.	        BindGridView(e.NewPageIndex); 
45.	    } 
46.	</script> 
47.	
48.	<html  > 
49.	<head runat="server"> 
50.	    <title>用GridView显示数据的例子</title> 
51.	</head> 
52.	<body> 
53.	    <form id="form1" runat="server"> 
54.	    <div> 
55.	         <asp:GridView ID="gvUserList" runat="server" AutoGenerateColumns="False" OnPageIndexChanging="gvUserList_PageIndexChanging"> 
56.	            <Columns> 
57.	                <asp:BoundField DataField="UserId" HeaderText="编号" /> 
58.	                <asp:HyperLinkField DataNavigateUrlFields="UserId" DetailsViewDemo.aspx?UserId={0}" 
59.	                    DataTextField="RealName" HeaderText="查看" /> 
60.	                <asp:BoundField DataField="UserName" HeaderText="用户名" /> 
61.	                <asp:BoundField DataField="RealName" HeaderText="真实姓名" /> 
62.	                <asp:BoundField DataField="Age" HeaderText="年龄" /> 
63.	                <asp:CheckBoxField DataField="Sex" HeaderText="男" /> 
64.	                <asp:BoundField DataField="Mobile" HeaderText="手机" /> 
65.	                <asp:TemplateField HeaderText="电子邮件"> 
66.	                    <AlternatingItemTemplate> 
67.	                        <a href='emailto:<%#Eval("Email") %>'>发电子给<%#Eval("RealName") %></a> 
68.	                    </AlternatingItemTemplate> 
69.	                    <ItemTemplate> 
70.	                        <%#Eval("Email") %> 
71.	                    </ItemTemplate> 
72.	                </asp:TemplateField> 
73.	            </Columns> 
74.	        </asp:GridView> 
75.	     
76.	    </div> 
77.	    </form> 
78.	</body> 
79.	</html>

下面是显示效果:

点击第二页的效果:

对于GridView 的用法笔者要说明几点:

1 、上面的代码采用了默认的自定义分页,这种分页每次翻页的时候都会将所有的数据全部从数据中取出来,根据当前页索引和每页要显示的记录条数决定要显示哪些记录,其它的数据会被丢弃掉,在数据量比较大的时候会导致性能低下。对于表中有大量数据的情况,需要自已写分页方法,每次只从数据库中取出需要显示的数据,提高网站的性能,并且根据当前页索引显示页面跳转导航链接,关于如何分页查询在本系列文章中ADO.NET 部分笔者已经讲过,这里不再赘述。

2 、当DataSource 中没有任何记录时,GridView 默认是没有任何显示的。我们还可以给GridView 添加一种效果,即当GridView 中没有任何数据时给用户提示。这个可以通过给GridView 添加EmptyDataTemplate 模版,定义没有数据数据时显示的内容,对上面的GridView 我们给它添加如果没有数据的功能。在<asp:GridView></asp:GridView> 添加如下内容:<EmptyDataTemplate> 温馨提示:当前没有任何记录哦。</EmptyDataTemplate> ,这时GridView 的定义如下:

复制代码

1.	<asp:GridView ID="gvUserList" runat="server" AutoGenerateColumns="False" OnPageIndexChanging="gvUserList_PageIndexChanging"> 
2.	            <Columns> 
3.	                <asp:BoundField DataField="UserId" HeaderText="编号" /> 
4.	                <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}" 
5.	                    DataTextField="RealName" HeaderText="查看" /> 
6.	                <asp:BoundField DataField="UserName" HeaderText="用户名" /> 
7.	                <asp:BoundField DataField="RealName" HeaderText="真实姓名" /> 
8.	                <asp:BoundField DataField="Age" HeaderText="年龄" /> 
9.	                <asp:CheckBoxField DataField="Sex" HeaderText="男" /> 
10.	                <asp:BoundField DataField="Mobile" HeaderText="手机" /> 
11.	                <asp:TemplateField HeaderText="电子邮件"> 
12.	                    <AlternatingItemTemplate> 
13.	                        <a href='emailto:<%#Eval("Email") %>'>发电子给<%#Eval("RealName") %></a> 
14.	                    </AlternatingItemTemplate> 
15.	                    <ItemTemplate> 
16.	                        <%#Eval("Email") %> 
17.	                    </ItemTemplate> 
18.	                </asp:TemplateField> 
19.	            </Columns> 
20.	            <EmptyDataTemplate> 
21.	                温馨提示:当前没有任何记录哦。 
22.	            </EmptyDataTemplate> 
23.	        </asp:GridView>

然后将我们的查询SQL 语句改为"select * from UserInfo where UserId>100000" ,这时的效果如下:

3 、如果当前的项显示样式不符合我们的要求的时候,我们可以设置项的显示样式,如下图:

4 、

注意: 在本例中数据绑定时都加了if (!Page.IsPostBack) 这种判断,这样做的目的是不会因为某个控件的提交页面导致整个页面的重新绑定,绝大部分情况下这种重新数据绑定是没有必要的、而且会影响网站的效率的。在实际开发中,各位朋友要区分这一情况。

GridView 中实现反选和全选功能

在显示数据的时候经常有一些批量操作的功能,比如数据的批量删除等,我们可以利用javascript 脚本来辅助实现这一功能,不过如果用asp.net 中的CheckBox 控件来实现这个功能的话,比较麻烦,因为在GridView 这样的控件将asp.net 中的Web 服务器控件转换成普通HTML 控件的时候不能直接按照控件的ID 来分配,存在着在一个GridView 中有多个CheckBox 控件,为了防止命名冲突,asp.net 为页上的各个服务器控件自动生成一个唯一的ClientID 值。ClientID 值是通过连接控件的 ID 值和它的父控件的 UniqueID 值生成的。如果未指定控件的 ID 值,则使用自动生成的值。如果我们在GridView 中添加一个CheckBox 控件,我们在生成的HTML 控件中会发现它生成的HTML 代码类似于下面的格式:

复制代码

1.	<input id="gvUserList_ctl02_ctl01" type="checkbox" name="gvUserList$ctl02$ctl01" checked="checked" disabled="disabled" />

所以我们在用javascript 操作GridView 这样的控件中的asp.net Web 服务器控件一定要注意这个情况,可以通过asp.net Web 服务器控件的ClientID 属性来操作。

这时候我们可以使用普通HTML 控件来达到我们想要的功能,asp.net 对于普通HTML 控件是不会更改它的id 和name 属性的。

实现了单选和复选功能之后,我们如何获取选中的值呢?因为是普通HTML 控件,自然不能像asp.net Web 服务器控件那样利用某个属性来判断,不过我们可以利用一个asp.net Button 服务器控件来提交表单,然后通过Request[“ 控件的name”] 来获取选中的值(没有印象的朋友赶紧看第三页的介绍),得到值是形如“15,16,17 ”这样的字符串,这时我们可以利用SQL 语句来进行批量操作,我们的SQL 语句可以这么写:

String sql=”delete from Users where UserId in(“+Request["CheckboxGroup"]+”)”;

这样就不必进行分割字符串的操作,只连接数据库操作就删除了选中的数据,大大提高了效率。

因为整个程序的代码比较复杂,所以采用了页面和代码分离的模式,前台代码如下:

复制代码

1.	<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MultiSelectGridView.aspx.cs" Inherits="MultiSelectGridView" %> 
2.	
3.	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
4.	
5.	<html  > 
6.	<head runat="server"> 
7.	    <title>在GridView中实现全选反选的例子</title> 
8.	    <script language="javascript" type="text/javascript"> 
9.	    //反选 
10.	    function ReverseSelect() 
11.	    { 
12.	        var checkbox = document.all.CheckboxGroup; 
13.	        if(checkbox==null) 
14.	        { 
15.	            return false;//zhoufoxcn modify 2007-12-25 
16.	        } 
17.	         
18.	        if(checkbox.length+""!="undefined") 
19.	        { 
20.	            for( var i=0;i<checkbox.length;i++ ) 
21.	            { 
22.	                checkbox[i].checked = !checkbox[i].checked; 
23.	            } 
24.	        } 
25.	        else 
26.	        { 
27.	            // 修正当列表长度为1时,不能反选的BUG 
28.	            checkbox.checked = !checkbox.checked; 
29.	        } 
30.	        return false;//zhoufoxcn modify 2007-12-25 
31.	         
32.	    } 
33.	    //全选 
34.	    function SelectAll() 
35.	    { 
36.	        var checkbox = document.all.CheckboxGroup; 
37.	        if(checkbox==null) 
38.	        { 
39.	            return false;//zhoufoxcn modify 2007-12-25 
40.	        } 
41.	         
42.	        if( checkbox.length+""!="undefined") 
43.	        { 
44.	            for( var i=0;i<checkbox.length;i++ ) 
45.	            { 
46.	                checkbox[i].checked = true; 
47.	            } 
48.	        } 
49.	        else 
50.	        { 
51.	            checkbox.checked = true; 
52.	        } 
53.	        return false;//zhoufoxcn modify 2007-12-25 
54.	    } 
55.	    //检查是否至少选择了一项 
56.	    function CheckHasSelectedItem() 
57.	    { 
58.	        var checkbox = document.all.CheckboxGroup; 
59.	        if(checkbox==null) 
60.	        { 
61.	            return false;//zhoufoxcn modify 2007-12-25 
62.	        } 
63.	         
64.	        if( checkbox.length+""!="undefined") 
65.	        { 
66.	            for( var i=0;i<checkbox.length;i++ ) 
67.	            { 
68.	                if(checkbox[i].checked) 
69.	                { 
70.	                    return true; 
71.	                } 
72.	            } 
73.	        } 
74.	        else 
75.	        { 
76.	            return false; 
77.	        } 
78.	    } 
79.	    //删除用户前的确认 
80.	    function ConfirmDelete() 
81.	    { 
82.	        if(CheckHasSelectedItem())//如果至少选择了一项 
83.	        { 
84.	            return confirm("确认删除选中的用户?"); 
85.	        } 
86.	        else 
87.	        { 
88.	            alert("请至少选择一项!"); 
89.	            return false; 
90.	        } 
91.	    } 
92.	    </script> 
93.	</head> 
94.	<body> 
95.	    <form id="form1" runat="server"> 
96.	    <div> 
97.	        <asp:GridView ID="gvUserList" runat="server" AutoGenerateColumns="False" Width="800px" AllowPaging="True" OnPageIndexChanging="gvUserList_PageIndexChanging" PageSize="5"> 
98.	            <Columns> 
99.	                <asp:TemplateField> 
100.	                <ItemTemplate> 
101.	                <input name='CheckboxGroup' type='checkbox' value='<%#Eval("UserId") %>'> 
102.	                </ItemTemplate> 
103.	                </asp:TemplateField> 
104.	                <asp:BoundField DataField="UserId" HeaderText="编号" /> 
105.	                <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}" 
106.	                    DataTextField="RealName" HeaderText="查看" /> 
107.	                <asp:BoundField DataField="UserName" HeaderText="用户名" /> 
108.	                <asp:BoundField DataField="RealName" HeaderText="真实姓名" /> 
109.	                <asp:BoundField DataField="Age" HeaderText="年龄" /> 
110.	                <asp:CheckBoxField DataField="Sex" HeaderText="男" /> 
111.	                <asp:BoundField DataField="Mobile" HeaderText="手机" /> 
112.	                <asp:TemplateField HeaderText="电子邮件"> 
113.	                    <AlternatingItemTemplate> 
114.	                        <a href='emailto:<%#Eval("Email") %>'>发电子给<%#Eval("RealName") %></a> 
115.	                    </AlternatingItemTemplate> 
116.	                    <ItemTemplate> 
117.	                        <%#Eval("Email") %> 
118.	                    </ItemTemplate> 
119.	                </asp:TemplateField> 
120.	            </Columns> 
121.	            <EmptyDataTemplate> 
122.	                温馨提示:当前没有任何记录哦。 
123.	            </EmptyDataTemplate> 
124.	             
125.	        </asp:GridView> 
126.	    <table border="0" width="800" cellpadding="0" cellspacing="0"> 
127.	    <tr><td><a style="text-decoration:underline" href="#" onclick="SelectAll();">全选</a></td> 
128.	    <td><a style="text-decoration:underline" href="#" onclick="ReverseSelect();">反选</a></td> 
129.	    <td> 
130.	        <asp:Button ID="btnDelete" runat="server" OnClientClick="javascript:return ConfirmDelete();" OnClick="btnDelete_Click" Text="删除" /></td> 
131.	    </tr> 
132.	    </table> 
133.	    </div> 
134.	    </form> 
135.	</body> 
136.	</html>

后台代码如下:

复制代码

1.	using System; 
2.	using System.Data; 
3.	using System.Configuration; 
4.	using System.Collections; 
5.	using System.Web; 
6.	using System.Web.Security; 
7.	using System.Web.UI; 
8.	using System.Web.UI.WebControls; 
9.	using System.Web.UI.WebControls.WebParts; 
10.	using System.Web.UI.HtmlControls; 
11.	using System.Data.SqlClient; 
12.	
13.	public partial class MultiSelectGridView : System.Web.UI.Page 
14.	{ 
15.	    protected void Page_Load(object sender, EventArgs e) 
16.	    { 
17.	        if (!Page.IsPostBack) 
18.	        { 
19.	            BindGridView(0); 
20.	        } 
21.	    } 
22.	    //指定绑定页面的数据 
23.	    private void BindGridView(int pageIndex) 
24.	    { 
25.	        //实例化Connection对象 
26.	        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
27.	        //实例化Command对象 
28.	        SqlCommand command = new SqlCommand("select * from UserInfo", connection); 
29.	        SqlDataAdapter adapter = new SqlDataAdapter(command); 
30.	        DataTable data = new DataTable(); 
31.	        adapter.Fill(data); 
32.	
33.	        gvUserList.DataSource = data; 
34.	        gvUserList.PageIndex = pageIndex;//设置当前显示第几页 
35.	        gvUserList.DataBind(); 
36.	    } 
37.	    //翻页事件 
38.	    protected void gvUserList_PageIndexChanging(object sender, GridViewPageEventArgs e) 
39.	    { 
40.	        //指定新页面,重新绑定数据 
41.	        BindGridView(e.NewPageIndex); 
42.	    } 
43.	    //删除选中的用户代码 
44.	    protected void btnDelete_Click(object sender, EventArgs e) 
45.	    { 
46.	        string sql = "delete from UserInfo where UserId in (" + Request["CheckboxGroup"] + ")"; 
47.	        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
48.	        SqlCommand command = new SqlCommand(sql, connection); 
49.	        connection.Open(); 
50.	        int count = command.ExecuteNonQuery(); 
51.	        connection.Close(); 
52.	        //删除成功后给出提示,并且跳转到当前页面 
53.	        if (count > 0) 
54.	        { 
55.	            Page.ClientScript.RegisterClientScriptBlock( 
56.	                this.GetType(), "success", 
57.	                "<script language='javascript'>alert('删除成功!');" 
58.	            + "window.location='MultiSelectGridView.aspx';</script>" 
59.	                ); 
60.	        } 
61.	        else//删除不成功给出不成功的提示 
62.	        { 
63.	            Page.ClientScript.RegisterClientScriptBlock( 
64.	                this.GetType(), "fail", 
65.	                "<script language='javascript'>alert('删除成功!');</script>" 
66.	                ); 
67.	        } 
68.	    } 
69.	}

页面的初始运行效果:

当一个也没有选择的时候点“删除”按钮之后的效果:

当选中一部分之后再点击“删除”的效果:

点击“确定”之后就会删除所有处于选中状态的用户,并且弹出删除成功的提示框,用户点击确定又会跳转到当前页面,显示删除选中用户之后的效果。

对上面的程序作如下说明:

1 、在页面的前台代码中使用了几个javascript 函数用于实现全选、反选和判断用户是否选择了至少一项及删除确认对话框的功能,“var checkbox = document.all.CheckboxGroup; ”这句代码的作用是获取当前页面中所有name 为”CheckboxGroup” 的HTML 控件,而我们在GridView 中所有的实现选择的复选框的name 属性就是”CheckboxGroup” 。

2 、在GridView 中可以使用普通HTML 控件或者asp.net 服务器控件,并且可以对它们的值或者某个属性进行绑定。

DataList 控件

DataList 是一个相对复杂一点的数据绑定控件,它需要使用者自己定义数据的展现格式,也就是需要在html 层控制数据的展示格式。和GridView 控件每行只能显示一条记录不同,DataList 可以在一行显示多条记录。

DataList 支持以下模版:AlternatingItemTemplate 、EditItemTemplate 、FooterTemplate 、HeaderTemplate 、ItemTemplate 和SelectedItemTemplate 及SeparatorTemplate 。其中AlternatingItemTemplate 、EditItemTemplate 、FooterTemplate 和HeaderTemplate 及ItemTemplate 在TemplateField 的支持的模版类型时已经介绍了,SelectedItemTemplatem 模版是当该项处于选中状态的效果,SeparatorTemplate 是各项之间分隔显示效果。

DataList 有两个重要属性,如下:

RepeatColumns :DataList 中要显示的列数。默认是0 ,即按照RepeatDirection 的设置单行或者单列显示数据。

RepeatDirection :DataList 的显示方式,这个属性是一个枚举值,有Horizontal 和Vertical 两个值,分别代表水平和垂直显示。

在使用DataList 时经常会嵌套绑定,所谓嵌套就是在一个数据绑定控件中嵌套着另一个数据绑定控件。下面演示一下DataList 进行嵌套绑定的效果。在这个效果里,首先将UserInfo 表中的数据按照性别分类,然后在每种性别里分别跳出三个用户显示。

首先向页面中添加一个DataList 控件,如下图:

点击“模版”,在它的ItemTemplate 模版中再添加一个Label 控件和一个DataList 控件,如下图:

对上述操作生成的前台代码我们做一些修改,如下:

复制代码

1.	<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DataListDemo.aspx.cs" Inherits="DataListDemo" %> 
2.	
3.	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
4.	
5.	<html  > 
6.	<head runat="server"> 
7.	    <title>DataList嵌套绑定的例子</title> 
8.	</head> 
9.	<body> 
10.	    <form id="form1" runat="server"> 
11.	    <div> 
12.	        <asp:DataList ID="DataList1" runat="server" RepeatColumns="2" RepeatDirection="Horizontal" OnItemDataBound="DataList1_ItemDataBound"> 
13.	            <ItemTemplate> 
14.	                <div style="background-color:Green"> 
15.	                <asp:Label ID="Label1" runat="server" Text='<%#Eval("Sex") %>' Visible="false"></asp:Label> 
16.	                <%#bool.Parse(Eval("Sex").ToString()) == true ? "男" : "女" %> 
17.	                </div> 
18.	                <asp:DataList ID="DataList2" runat="server"> 
19.	                <ItemTemplate> 
20.	                <%#Eval("RealName") %> 
21.	                </ItemTemplate> 
22.	                </asp:DataList> 
23.	            </ItemTemplate> 
24.	        </asp:DataList></div> 
25.	    </form> 
26.	</body> 
27.	</html>

后台代码如下:

复制代码

1.	using System; 
2.	using System.Data; 
3.	using System.Configuration; 
4.	using System.Collections; 
5.	using System.Web; 
6.	using System.Web.Security; 
7.	using System.Web.UI; 
8.	using System.Web.UI.WebControls; 
9.	using System.Web.UI.WebControls.WebParts; 
10.	using System.Web.UI.HtmlControls; 
11.	using System.Data.SqlClient; 
12.	
13.	public partial class DataListDemo : System.Web.UI.Page 
14.	{ 
15.	    protected void Page_Load(object sender, EventArgs e) 
16.	    { 
17.	        if (!Page.IsPostBack) 
18.	        { 
19.	            BindSex(); 
20.	        } 
21.	    } 
22.	    //绑定顶级项目 
23.	    private void BindSex() 
24.	    { 
25.	        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
26.	        SqlCommand command = new SqlCommand("select distinct sex from UserInfo", connection); 
27.	        SqlDataAdapter adapter = new SqlDataAdapter(command); 
28.	        DataTable data = new DataTable(); 
29.	        adapter.Fill(data); 
30.	
31.	        DataList1.DataSource = data; 
32.	        DataList1.DataBind(); 
33.	    } 
34.	    //当绑定DataList1中的每一项时的处理方法 
35.	    protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e) 
36.	    { 
37.	        //如果要绑定的项是交替项或者是普通项 
38.	        //注意此外还有脚模板和脚模版 
39.	        if (e.Item.ItemType == ListItemType.Item || 
40.	             e.Item.ItemType == ListItemType.AlternatingItem) 
41.	        { 
42.	            //e.Item表示当前绑定的那一行 
43.	            //利用e.Item.FindControl("Label1")来找到那一行的id为"Label1"的Label控件 
44.	            Label lbSex = (Label)(e.Item.FindControl("Label1")); 
45.	            //利用e.Item.FindControl("Label1")来找到那一行的id为"Label1"的Label控件 
46.	            DataList dl2 = (DataList)(e.Item.FindControl("DataList2")); 
47.	
48.	            bool male = bool.Parse(lbSex.Text); 
49.	            dl2.DataSource = GetDataTable(male); 
50.	            dl2.DataBind(); 
51.	        } 
52.	    } 
53.	    /// <summary> 
54.	    /// 根据性别来查找符合条件的用户 
55.	    /// </summary> 
56.	    /// <param name="male">是否为男性</param> 
57.	    /// <returns></returns> 
58.	    private DataTable GetDataTable(bool male) 
59.	    { 
60.	        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
61.	        SqlCommand command = new SqlCommand("select top 3 RealName from UserInfo where Sex=@Sex order by UserID", connection); 
62.	        command.Parameters.AddWithValue("@Sex", male);//添加SqlParameter参数 
63.	        SqlDataAdapter adapter = new SqlDataAdapter(command); 
64.	        DataTable data = new DataTable(); 
65.	        adapter.Fill(data); 
66.	        return data; 
67.	    } 
68.	}

页面的最后运行效果:

对上面的程序代码作几点说明:

(1 )在上面的代码中使用了两个DataList 控件,其中第二个是位于第一个的ItemTemplate 模版里面,这个用于绑定符合当前项中条件的数据,并且我们在第一个的ItemTemplate 里面还用到了一个Label 控件,这个Label 是不可见的(Visible="false" ),使用这个控件并不是为了显示数据,而是为了保存第二个DataList 要绑定显示的数据的条件。在这里我们是以性别作为顶级分类的,其实这个没有必要在数据库查询并进行绑定显示,这里只是通过这种方法来演示DataList 如何进行嵌套绑定。

(2 )在嵌套绑定的时候我们利用了DataList 的ItemDataBound 事件,在绑定DataList 中的每一项时候都会激发这个事件,当要绑定的项是普通项或者是交替项时,项模版里就有要显示子数据的DataList 控件和我们隐藏Label 控件,我们利用FindControl() 方法找到这两个控件,利用Label 的Text 属性值作为条件去数据库查找满足条件的数据,并将返回的数据源绑定到第二个DataList 上,这样就完成了DataList 的嵌套绑定。

Repeater 控件

Repeater 控件的用法类似于DataList 控件,只不过它不能在一行显示多行数据,不过它可以让我们更灵活地控制数据的显示样式。如果Repeater 控件中没有定义模版或者模版中没有定义要显示的数据的显示方式,那么在运行时该控件在页面上不会有任何显示。

Repeater 服务器控件支持的模版有ItemTemplate 、AlternatingItemTemplate 、HeaderTemplate 和FooterTemplate 及SeparatorTemplate ,这些模版的用法类似于DataList 中对应的模版的用法。

下面是Repeater 控件的用法的例子。

首先在页面中拖入一个Repeater 控件,拖入Repeater 控件之后页面的设计效果如下:

可以看出使用Repeater 控件时没有办法在设计视图下编辑控件模版,要编辑控件模版需要切换到源视图。

在ADO.NET 一节笔者展示了如何用Table 来显示数据,具体做法是现在循环之前输出表头,然后在利用循环输出数据集合中的每条数据,最后在循环结束之后输出table 的结束标记。如果在Repeater 中想用Table 的形式显示数据,我们的做法是如下:

先在HeaderTemplate 模版中定义表头,然后在ItemTemplate 模版或AlternatingItemTemplate 模版中定义数据的每条数据的显示方式,最后在FooterTemplate 模版中定义table 的结束标记。

下面是前台代码:

复制代码

1.	<%@ Page Language="C#" AutoEventWireup="true" CodeFile="RepeaterDemo.aspx.cs" Inherits="RepeaterDemo" %> 
2.	
3.	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
4.	
5.	<html  > 
6.	<head runat="server"> 
7.	    <title>Repeater服务器控件使用的例子</title> 
8.	</head> 
9.	<body> 
10.	    <form id="form1" runat="server"> 
11.	    <div> 
12.	        <asp:Repeater ID="Repeater1" runat="server"> 
13.	        <HeaderTemplate> 
14.	        <table border="1" cellpadding="0" cellspacing="0"> 
15.	    <tr><td>编号</td><td>真实姓名</td><td>年龄</td><td>性别</td><td>手机</td><td>电话</td><td>电子邮件</td></tr> 
16.	        </HeaderTemplate> 
17.	        <ItemTemplate> 
18.	        <tr><td><%#Eval("UserID") %></td><td><%#Eval("RealName") %></td><td><%#Eval("Age") %></td><td><%#bool.Parse(Eval("sex").ToString())?"男":"<font color='green'>女</font>" %></td><td><%#Eval("Mobile") %></td><td><%#Eval("Phone") %></td><td><%#Eval("Email") %></td></tr> 
19.	        </ItemTemplate> 
20.	        <AlternatingItemTemplate> 
21.	        <tr><td><input type="text" readonly="readonly" value='<%#Eval("UserId") %>' size="2" /></td><td><%#Eval("RealName") %></td><td><%#Eval("Age") %></td><td><%#bool.Parse(Eval("sex").ToString())?"男":"<font color='green'>女</font>" %></td><td><%#Eval("Mobile") %></td><td><%#Eval("Phone") %></td><td><%#Eval("Email") %></td></tr> 
22.	        </AlternatingItemTemplate> 
23.	        <FooterTemplate> 
24.	        </table> 
25.	        </FooterTemplate> 
26.	        </asp:Repeater> 
27.	    </div> 
28.	    </form> 
29.	</body> 
30.	</html>

下面是后台代码:

复制代码

1.	using System; 
2.	using System.Data; 
3.	using System.Configuration; 
4.	using System.Collections; 
5.	using System.Web; 
6.	using System.Web.Security; 
7.	using System.Web.UI; 
8.	using System.Web.UI.WebControls; 
9.	using System.Web.UI.WebControls.WebParts; 
10.	using System.Web.UI.HtmlControls; 
11.	using System.Data.SqlClient; 
12.	
13.	public partial class RepeaterDemo : System.Web.UI.Page 
14.	{ 
15.	    protected void Page_Load(object sender, EventArgs e) 
16.	    { 
17.	        //仅当页面不是由页面的服务器控件提交表单而导致的页面加载才会绑定数据 
18.	        if (!Page.IsPostBack) 
19.	        { 
20.	            //实例化Connection对象 
21.	            SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
22.	            //实例化Command对象 
23.	            string sql="select top 5 * from UserInfo order by UserID desc"; 
24.	            SqlDataAdapter adapter = new SqlDataAdapter(sql, connection); 
25.	            DataTable data = new DataTable(); 
26.	            adapter.Fill(data); 
27.	
28.	            Repeater1.DataSource = data; 
29.	            Repeater1.DataBind(); 
30.	        } 
31.	    } 
32.	}

以下是页面的显示效果:

在这里例子里我们定义了交替项的显示效果,偶数行的编号是以文本框的形式展示,并且我们对用户性别做了处理之后才显示。

前面讲到的GridView 和DataList 及Repeater 控件是用来批量显示数据的,在这种情况下只显示数据库记录的概要信息,比如要显示论坛某个版块下的文章列表时肯定不会同时将文章内容页也是显示出来(为了提高查询效率实际开发中文章内容字段都不会出现在select 查询SQL 语句的字段列表中)。如果用户对某条记录感兴趣可以点击给定的超级链接来查看。这时我们就可以利用FormView 或者DetailsView 控件,它们就是用来显示单条记录的详细信息的。

FormView 控件

Form 控件的用法和Repeater 控件的用法非常类似,它支持模版类型有EditItemTemplate 、EmptyDataTemplate 、FooterTemplate 、HeaderTemplate 、ItemTemplate 和InsertItemTemplate 、PagerTemplate ,注意这里没有AlternatingItemTemplate 模版(就一条记录自然就不会有什么奇偶行效果了)。

FormView 控件支持以下功能:

绑定到数据源控件,如 SqlDataSource 和 ObjectDataSource 。

内置插入功能。

内置更新和删除功能。

内置分页功能。

以编程方式访问 FormView 对象模型以动态设置属性、处理事件等。

可通过用户定义的模板、主题和样式自定义外观。

需要特别说明的是笔者只是说FormView 控件一次只能显示一条数据,但是如果绑定的数据源有多条记录的时候,默认是显示第一条记录,但是还能支持像GridView 那样分页显示数据源中的每条记录。

下面是FormView 用法的例子,在本例中设置了允许分页显示,前台代码如下:

复制代码

1.	<%@ Page Language="C#" AutoEventWireup="true" CodeFile="FormViewDemo.aspx.cs" Inherits="FormViewDemo" %> 
2.	
3.	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
4.	
5.	<html  > 
6.	<head runat="server"> 
7.	    <title>FormView分页显示数据的例子</title> 
8.	</head> 
9.	<body> 
10.	    <form id="form1" runat="server"> 
11.	    <div> 
12.	        <asp:FormView ID="FormView1" runat="server" AllowPaging="True" OnPageIndexChanging="FormView1_PageIndexChanging"> 
13.	            <HeaderTemplate> 
14.	        <table border="1" cellpadding="0" cellspacing="0"> 
15.	    <tr><td>编号</td><td>真实姓名</td><td>年龄</td><td>性别</td><td>手机</td><td>电话</td><td>电子邮件</td></tr> 
16.	        </HeaderTemplate> 
17.	        <ItemTemplate> 
18.	        <tr><td><%#Eval("UserID") %></td><td><%#Eval("RealName") %></td><td><%#Eval("Age") %></td><td><%#bool.Parse(Eval("sex").ToString())?"男":"<font color='green'>女</font>" %></td><td><%#Eval("Mobile") %></td><td><%#Eval("Phone") %></td><td><%#Eval("Email") %></td></tr> 
19.	        </ItemTemplate> 
20.	        <FooterTemplate> 
21.	        </table> 
22.	        </FooterTemplate> 
23.	        </asp:FormView> 
24.	    </div> 
25.	    </form> 
26.	</body> 
27.	</html>

后台代码如下:

复制代码

1.	using System; 
2.	using System.Data; 
3.	using System.Configuration; 
4.	using System.Collections; 
5.	using System.Web; 
6.	using System.Web.Security; 
7.	using System.Web.UI; 
8.	using System.Web.UI.WebControls; 
9.	using System.Web.UI.WebControls.WebParts; 
10.	using System.Web.UI.HtmlControls; 
11.	using System.Data.SqlClient; 
12.	
13.	public partial class FormViewDemo : System.Web.UI.Page 
14.	{ 
15.	    protected void Page_Load(object sender, EventArgs e) 
16.	    { 
17.	        if (!Page.IsPostBack) 
18.	        { 
19.	            BindData(0); 
20.	        } 
21.	    } 
22.	    private void BindData(int pageIndex) 
23.	    { 
24.	        //实例化Connection对象 
25.	        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
26.	        //实例化Command对象 
27.	        string sql = "select top 5 * from UserInfo order by UserID desc"; 
28.	        SqlDataAdapter adapter = new SqlDataAdapter(sql, connection); 
29.	        DataTable data = new DataTable(); 
30.	        adapter.Fill(data); 
31.	
32.	        FormView1.DataSource = data; 
33.	        FormView1.PageIndex = pageIndex; 
34.	        FormView1.DataBind(); 
35.	    } 
36.	    protected void FormView1_PageIndexChanging(object sender, FormViewPageEventArgs e) 
37.	    { 
38.	        BindData(e.NewPageIndex); 
39.	    } 
40.	}

下面是运行效果:

DetailsView 控件

DetailsView 控件主要是以表格的形式来显示和处理来自数据源的单条数据。它支持绑定功能( 即可以使用DataBind() 方法) 和分页及编辑等功能,它一般与GridView 控件搭配使用,用GridView 控件显示数据记录列表,用DetailsView 显示某条记录的详细信息。DetailsView 控件的用法也很类似于GridView 控件。

下面是DetailsView 控件控件的例子。

前台代码如下:

复制代码

1.	<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DetailsViewDemo.aspx.cs" Inherits="DetailsViewDemo" %> 
2.	
3.	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
4.	
5.	<html  > 
6.	<head runat="server"> 
7.	    <title>DetailsView控件的例子</title> 
8.	</head> 
9.	<body> 
10.	    <form id="form1" runat="server"> 
11.	    <div> 
12.	        <asp:DetailsView ID="DetailsView1" runat="server"  Width="400px" AutoGenerateRows="False"> 
13.	        <Fields> 
14.	                <asp:BoundField DataField="UserId" HeaderText="编号" /> 
15.	                <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}" 
16.	                    DataTextField="RealName" HeaderText="查看" /> 
17.	                <asp:BoundField DataField="UserName" HeaderText="用户名" /> 
18.	                <asp:BoundField DataField="RealName" HeaderText="真实姓名" /> 
19.	                <asp:BoundField DataField="Age" HeaderText="年龄" /> 
20.	                <asp:CheckBoxField DataField="Sex" HeaderText="男" /> 
21.	                <asp:BoundField DataField="Mobile" HeaderText="手机" /> 
22.	                <asp:TemplateField HeaderText="电子邮件"> 
23.	                    <AlternatingItemTemplate> 
24.	                        <a href='emailto:<%#Eval("Email") %>'>发电子给<%#Eval("RealName") %></a> 
25.	                    </AlternatingItemTemplate> 
26.	                    <ItemTemplate> 
27.	                        <%#Eval("Email") %> 
28.	                    </ItemTemplate> 
29.	                </asp:TemplateField> 
30.	            </Fields> 
31.	            <EmptyDataTemplate> 
32.	                温馨提示:当前没有任何记录哦。 
33.	            </EmptyDataTemplate> 
34.	        </asp:DetailsView> 
35.	     
36.	    </div> 
37.	    </form> 
38.	</body> 
39.	</html>

后台代码如下:

复制代码

1.	using System; 
2.	using System.Data; 
3.	using System.Configuration; 
4.	using System.Collections; 
5.	using System.Web; 
6.	using System.Web.Security; 
7.	using System.Web.UI; 
8.	using System.Web.UI.WebControls; 
9.	using System.Web.UI.WebControls.WebParts; 
10.	using System.Web.UI.HtmlControls; 
11.	using System.Data.SqlClient; 
12.	
13.	public partial class DetailsViewDemo : System.Web.UI.Page 
14.	{ 
15.	    protected void Page_Load(object sender, EventArgs e) 
16.	    { 
17.	        if (!Page.IsPostBack) 
18.	        { 
19.	            int userId; 
20.	            //当当前URL地址中含有"UserId"参数并且能转换成数字时 
21.	            if (int.TryParse(Request.QueryString["UserId"], out userId)) 
22.	            { 
23.	                //实例化Connection对象 
24.	                SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa"); 
25.	                //实例化Command对象 
26.	                SqlCommand command = new SqlCommand("select * from UserInfo where UserId=@UserId", connection); 
27.	                command.Parameters.AddWithValue("@UserId", userId);//添加Parameter参数 
28.	                SqlDataAdapter adapter = new SqlDataAdapter(command); 
29.	                DataTable data = new DataTable(); 
30.	                adapter.Fill(data); 
31.	
32.	                DetailsView1.DataSource = data; 
33.	                DetailsView1.DataBind(); 
34.	            } 
35.	            else 
36.	            { 
37.	                //如果不能转换成数字,生成一个空DataTable对象来绑定 
38.	                //因为我们在设计代码中定义如果没有符合条件的数据时的显示效果 
39.	                //所以此时会显示我们定义的没有数据时的效果 
40.	                DataTable data = new DataTable(); 
41.	                DetailsView1.DataSource = data; 
42.	                DetailsView1.DataBind(); 
43.	            } 
44.	        } 
45.	    } 
46.	}

还记得前面使用GridView 显示数据的例子吗?我们可以从那里开始,因为在前面的GridView 例子中我们定义了一个查看数据详情的超级链接的例子,那里我们还使用了一个HyperLinkField ,它的定义如下:

复制代码

1.	<asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}" 
2.	                    DataTextField="RealName" HeaderText="查看" />

我们就GridView 开始查看所有的记录,然后选择任意一条记录查看详细信息(这里选择查看周公也就是我的个人信息),效果如下:

(注:本系列文章所有有关联系信息都是虚假的,请读者朋友不要当真,所以我的信息除了年龄之外也都是假的:P )

因为我们还定义了没有满足条件的情况的提示信息,所以如果不提供任何参数或者找不到相关记录的时候,会看到如下效果:

另外说明一下,笔者实际开发中用到FormView 和DetailsView 控件的机会很小,因为一般都将添加和编辑功能放到一个页面中了,而且能比较方便地使用下一篇要介绍的验证控件。

总结:

GridView 、DataList 和Repeater 控件适合一次性显示多条数据概要的情况下,它们对呈现数据的控制能力是GridView 较弱,DataList 次之,Repeater 因为使用者完全可以自己编写呈现的HTML 代码来控制呈现方式所以对数据呈现方式方面控制最强,在使用便捷性上来说GridView 因为内置了表格呈现样式并且了内置了分页和排序等方面的功能所以较容易操作,DataList 次之,Repeater 因为使用者完全自己编写呈现的HTML 代码所以较难使用。如果仅仅呈现一下数据,可以考虑使用GridView 控件,如果需要将数据分成多列显示只能使用DataList 控件,如果想使用复杂的呈现方式则可以考虑使用Repeater 控件。

FormView 与DetailsView 控件有很多相似的地方,二者都是用来显示某一详细记录,都是只能显示一条数据源中的记录。并且都具有分页的能力。并且都支持显示、编辑和添加等功能。但是二者也有不同点:具体表现在DetailsView 内置了表格呈现样式,并且显示相关数据的字段名称和数据值。FormView 则需要自己写相关的HTML 代码。另外,DetailsView 有AutoGenerateField 属性或者自定义Fileds 属性,控件能够自动创建相关模版属性,而FormView 控件的呈现形式完全依赖模版设置。另外一般来说DetailsView 控件将数据源中的每一个字段用一行来显示,而FormView 控件将数据源中每一条记录用一行来显示。

因为去北京参加MVP Open Day 活动在北京呆了几天,在北京的几天没有时间来写文章(可以看本人的《MVP Open Day 趣事记》看看本人在北京发生了哪些有趣的事情),加上微软山西.net 俱乐部最近再搞一系列走进高校的活动,所以时间比较少,所以本月写的夜话比较少,看到不少朋友在我的博客上留言鼓励和催下篇,很受鼓舞也很感动,昨夜我写到今早3 点才睡,早晨7 点半又爬起来上班了。我初步排了一个计划,大概这个夜话系列会有21 篇左右的文章,我计划在元旦前写完,压力很大,不过我动力更大:)能让更多的人从这个系列的文章中学到知识就是我最大的动力!

另外,如果大家对这个系列有什么好的建议或者很希望我来讲述有关asp.net 中的某些知识点,请在我的博客 http://blog.csdn.net/zhoufoxcn 留言告诉我,我一定会尽量满足大家的要求。

posted @ 2009-03-02 22:59  无很  阅读(525)  评论(0编辑  收藏  举报