数据绑定控件收藏 GridView DataList Repeater FormView DetailsView

图片、详情见http://blog.csdn.net/txl816/archive/2008/10/27/3158796.aspx

 

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,用来显示一个超级链接,它的设置如下:

<asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}"
                    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表中的数据的例子,对于奇数行用户的电子邮件仅仅显示电子邮件地址,偶数行的用户显示为超级链接。以下是代码:

 

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            //默认显示第一页,不过在GridView中第一页的页索引是0
            //注意:在C#中集合里的索引也都是以0开始
            BindGridView(0);
        }
    }
    //指定绑定页面的数据
    private void BindGridView(int pageIndex)
    {
        //实例化Connection对象
        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
        //实例化Command对象
        SqlCommand command = new SqlCommand("select * from UserInfo", connection);
        SqlDataAdapter adapter = new SqlDataAdapter(command);
        DataTable data = new DataTable();
        adapter.Fill(data);

        #region 注意这部分代码可以在设计视图中设置,不必写在代码里
        gvUserList.AllowPaging = true;//设置允许自动分页
        //gvUserList.AutoGenerateColumns = false;//设置不允许自动绑定列
        gvUserList.PageSize = 5;//设置每页显示5条记录
        #endregion
        
        gvUserList.DataSource = data;
        gvUserList.PageIndex = pageIndex;//设置当前显示第几页
        gvUserList.DataBind();
    }

    //翻页事件
    protected void gvUserList_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        //指定新页面,重新绑定数据
        BindGridView(e.NewPageIndex);
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>用GridView显示数据的例子</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
         <asp:GridView ID="gvUserList" runat="server" AutoGenerateColumns="False" OnPageIndexChanging="gvUserList_PageIndexChanging">
            <Columns>
                <asp:BoundField DataField="UserId" HeaderText="编号" />
                <asp:HyperLinkField DataNavigateUrlFields="UserId" DetailsViewDemo.aspx?UserId={0}"
                    DataTextField="RealName" HeaderText="查看" />
                <asp:BoundField DataField="UserName" HeaderText="用户名" />
                <asp:BoundField DataField="RealName" HeaderText="真实姓名" />
                <asp:BoundField DataField="Age" HeaderText="年龄" />
                <asp:CheckBoxField DataField="Sex" HeaderText="男" />
                <asp:BoundField DataField="Mobile" HeaderText="手机" />
                <asp:TemplateField HeaderText="电子邮件">
                    <AlternatingItemTemplate>
                        <a href='emailto:<%#Eval("Email") %>'>发电子给<%#Eval("RealName") %></a>
                    </AlternatingItemTemplate>
                    <ItemTemplate>
                        <%#Eval("Email") %>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    
    </div>
    </form>
</body>
</html>
下面是显示效果:

 


点击第二页的效果:

 


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

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

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

 

<asp:GridView ID="gvUserList" runat="server" AutoGenerateColumns="False" OnPageIndexChanging="gvUserList_PageIndexChanging">
            <Columns>
                <asp:BoundField DataField="UserId" HeaderText="编号" />
                <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}"
                    DataTextField="RealName" HeaderText="查看" />
                <asp:BoundField DataField="UserName" HeaderText="用户名" />
                <asp:BoundField DataField="RealName" HeaderText="真实姓名" />
                <asp:BoundField DataField="Age" HeaderText="年龄" />
                <asp:CheckBoxField DataField="Sex" HeaderText="男" />
                <asp:BoundField DataField="Mobile" HeaderText="手机" />
                <asp:TemplateField HeaderText="电子邮件">
                    <AlternatingItemTemplate>
                        <a href='emailto:<%#Eval("Email") %>'>发电子给<%#Eval("RealName") %></a>
                    </AlternatingItemTemplate>
                    <ItemTemplate>
                        <%#Eval("Email") %>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <EmptyDataTemplate>
                温馨提示:当前没有任何记录哦。
            </EmptyDataTemplate>
        </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代码类似于下面的格式:

 

<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"]+”)”;

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

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

 

 


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MultiSelectGridView.aspx.cs" Inherits="MultiSelectGridView" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>在GridView中实现全选反选的例子</title>
    <script language="javascript" type="text/javascript">
    //反选
    function ReverseSelect()
    {
        var checkbox = document.all.CheckboxGroup;
        if(checkbox==null)
        {
            return false;//zhoufoxcn modify 2007-12-25
        }
        
        if(checkbox.length+""!="undefined")
        {
            for( var i=0;i<checkbox.length;i++ )
            {
                checkbox[i].checked = !checkbox[i].checked;
            }
        }
        else
        {
            // 修正当列表长度为1时,不能反选的BUG
            checkbox.checked = !checkbox.checked;
        }
        return false;//zhoufoxcn modify 2007-12-25
        
    }
    //全选
    function SelectAll()
    {
        var checkbox = document.all.CheckboxGroup;
        if(checkbox==null)
        {
            return false;//zhoufoxcn modify 2007-12-25
        }
        
        if( checkbox.length+""!="undefined")
        {
            for( var i=0;i<checkbox.length;i++ )
            {
                checkbox[i].checked = true;
            }
        }
        else
        {
            checkbox.checked = true;
        }
        return false;//zhoufoxcn modify 2007-12-25
    }
    //检查是否至少选择了一项
    function CheckHasSelectedItem()
    {
        var checkbox = document.all.CheckboxGroup;
        if(checkbox==null)
        {
            return false;//zhoufoxcn modify 2007-12-25
        }
        
        if( checkbox.length+""!="undefined")
        {
            for( var i=0;i<checkbox.length;i++ )
            {
                if(checkbox[i].checked)
                {
                    return true;
                }
            }
        }
        else
        {
            return false;
        }
    }
    //删除用户前的确认
    function ConfirmDelete()
    {
        if(CheckHasSelectedItem())//如果至少选择了一项
        {
            return confirm("确认删除选中的用户?");
        }
        else
        {
            alert("请至少选择一项!");
            return false;
        }
    }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="gvUserList" runat="server" AutoGenerateColumns="False" Width="800px" AllowPaging="True" OnPageIndexChanging="gvUserList_PageIndexChanging" PageSize="5">
            <Columns>
                <asp:TemplateField>
                <ItemTemplate>
                <input name='CheckboxGroup' type='checkbox' value='<%#Eval("UserId") %>'>
                </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="UserId" HeaderText="编号" />
                <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}"
                    DataTextField="RealName" HeaderText="查看" />
                <asp:BoundField DataField="UserName" HeaderText="用户名" />
                <asp:BoundField DataField="RealName" HeaderText="真实姓名" />
                <asp:BoundField DataField="Age" HeaderText="年龄" />
                <asp:CheckBoxField DataField="Sex" HeaderText="男" />
                <asp:BoundField DataField="Mobile" HeaderText="手机" />
                <asp:TemplateField HeaderText="电子邮件">
                    <AlternatingItemTemplate>
                        <a href='emailto:<%#Eval("Email") %>'>发电子给<%#Eval("RealName") %></a>
                    </AlternatingItemTemplate>
                    <ItemTemplate>
                        <%#Eval("Email") %>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <EmptyDataTemplate>
                温馨提示:当前没有任何记录哦。
            </EmptyDataTemplate>
            
        </asp:GridView>
    <table border="0" width="800" cellpadding="0" cellspacing="0">
    <tr><td><a style="text-decoration:underline" href="#" οnclick="SelectAll();">全选</a></td>
    <td><a style="text-decoration:underline" href="#" οnclick="ReverseSelect();">反选</a></td>
    <td>
        <asp:Button ID="btnDelete" runat="server" OnClientClick="javascript:return ConfirmDelete();" OnClick="btnDelete_Click" Text="删除" /></td>
    </tr>
    </table>
    </div>
    </form>
</body>
</html>
后台代码如下:

 

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

public partial class MultiSelectGridView : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            BindGridView(0);
        }
    }
    //指定绑定页面的数据
    private void BindGridView(int pageIndex)
    {
        //实例化Connection对象
        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
        //实例化Command对象
        SqlCommand command = new SqlCommand("select * from UserInfo", connection);
        SqlDataAdapter adapter = new SqlDataAdapter(command);
        DataTable data = new DataTable();
        adapter.Fill(data);

        gvUserList.DataSource = data;
        gvUserList.PageIndex = pageIndex;//设置当前显示第几页
        gvUserList.DataBind();
    }
    //翻页事件
    protected void gvUserList_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        //指定新页面,重新绑定数据
        BindGridView(e.NewPageIndex);
    }
    //删除选中的用户代码
    protected void btnDelete_Click(object sender, EventArgs e)
    {
        string sql = "delete from UserInfo where UserId in (" + Request["CheckboxGroup"] + ")";
        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
        SqlCommand command = new SqlCommand(sql, connection);
        connection.Open();
        int count = command.ExecuteNonQuery();
        connection.Close();
        //删除成功后给出提示,并且跳转到当前页面
        if (count > 0)
        {
            Page.ClientScript.RegisterClientScriptBlock(
                this.GetType(), "success",
                "<script language='javascript'>alert('删除成功!');"
            + "window.location='MultiSelectGridView.aspx';</script>"
                );
        }
        else//删除不成功给出不成功的提示
        {
            Page.ClientScript.RegisterClientScriptBlock(
                this.GetType(), "fail",
                "<script language='javascript'>alert('删除成功!');</script>"
                );
        }
    }
}
页面的初始运行效果:

 


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

 


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

 


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

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

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控件,如下图:

 


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

 

 


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DataListDemo.aspx.cs" Inherits="DataListDemo" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>DataList嵌套绑定的例子</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:DataList ID="DataList1" runat="server" RepeatColumns="2" RepeatDirection="Horizontal" OnItemDataBound="DataList1_ItemDataBound">
            <ItemTemplate>
                <div style="background-color:Green">
                <asp:Label ID="Label1" runat="server" Text='<%#Eval("Sex") %>' Visible="false"></asp:Label>
                <%#bool.Parse(Eval("Sex").ToString()) == true ? "男" : "女" %>
                </div>
                <asp:DataList ID="DataList2" runat="server">
                <ItemTemplate>
                <%#Eval("RealName") %>
                </ItemTemplate>
                </asp:DataList>
            </ItemTemplate>
        </asp:DataList></div>
    </form>
</body>
</html>
后台代码如下:

 

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

public partial class DataListDemo : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            BindSex();
        }
    }
    //绑定顶级项目
    private void BindSex()
    {
        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
        SqlCommand command = new SqlCommand("select distinct sex from UserInfo", connection);
        SqlDataAdapter adapter = new SqlDataAdapter(command);
        DataTable data = new DataTable();
        adapter.Fill(data);

        DataList1.DataSource = data;
        DataList1.DataBind();
    }
    //当绑定DataList1中的每一项时的处理方法
    protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
    {
        //如果要绑定的项是交替项或者是普通项
        //注意此外还有脚模板和脚模版
        if (e.Item.ItemType == ListItemType.Item ||
             e.Item.ItemType == ListItemType.AlternatingItem)
        {
            //e.Item表示当前绑定的那一行
            //利用e.Item.FindControl("Label1")来找到那一行的id为"Label1"的Label控件
            Label lbSex = (Label)(e.Item.FindControl("Label1"));
            //利用e.Item.FindControl("Label1")来找到那一行的id为"Label1"的Label控件
            DataList dl2 = (DataList)(e.Item.FindControl("DataList2"));

            bool male = bool.Parse(lbSex.Text);
            dl2.DataSource = GetDataTable(male);
            dl2.DataBind();
        }
    }
    /// <summary>
    /// 根据性别来查找符合条件的用户
    /// </summary>
    /// <param name="male">是否为男性</param>
    /// <returns></returns>
    private DataTable GetDataTable(bool male)
    {
        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
        SqlCommand command = new SqlCommand("select top 3 RealName from UserInfo where Sex=@Sex order by UserID", connection);
        command.Parameters.AddWithValue("@Sex", male);//添加SqlParameter参数
        SqlDataAdapter adapter = new SqlDataAdapter(command);
        DataTable data = new DataTable();
        adapter.Fill(data);
        return data;
    }
}
页面的最后运行效果:

 


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

(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的结束标记。

下面是前台代码:

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="RepeaterDemo.aspx.cs" Inherits="RepeaterDemo" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Repeater服务器控件使用的例子</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater ID="Repeater1" runat="server">
        <HeaderTemplate>
        <table border="1" cellpadding="0" cellspacing="0">
    <tr><td>编号</td><td>真实姓名</td><td>年龄</td><td>性别</td><td>手机</td><td>电话</td><td>电子邮件</td></tr>
        </HeaderTemplate>
        <ItemTemplate>
        <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>
        </ItemTemplate>
        <AlternatingItemTemplate>
        <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>
        </AlternatingItemTemplate>
        <FooterTemplate>
        </table>
        </FooterTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>
下面是后台代码:

 

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

public partial class RepeaterDemo : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //仅当页面不是由页面的服务器控件提交表单而导致的页面加载才会绑定数据
        if (!Page.IsPostBack)
        {
            //实例化Connection对象
            SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
            //实例化Command对象
            string sql="select top 5 * from UserInfo order by UserID desc";
            SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
            DataTable data = new DataTable();
            adapter.Fill(data);

            Repeater1.DataSource = data;
            Repeater1.DataBind();
        }
    }
}
以下是页面的显示效果:

 


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

 

前面讲到的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用法的例子,在本例中设置了允许分页显示,前台代码如下:

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="FormViewDemo.aspx.cs" Inherits="FormViewDemo" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>FormView分页显示数据的例子</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:FormView ID="FormView1" runat="server" AllowPaging="True" OnPageIndexChanging="FormView1_PageIndexChanging">
            <HeaderTemplate>
        <table border="1" cellpadding="0" cellspacing="0">
    <tr><td>编号</td><td>真实姓名</td><td>年龄</td><td>性别</td><td>手机</td><td>电话</td><td>电子邮件</td></tr>
        </HeaderTemplate>
        <ItemTemplate>
        <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>
        </ItemTemplate>
        <FooterTemplate>
        </table>
        </FooterTemplate>
        </asp:FormView>
    </div>
    </form>
</body>
</html>
后台代码如下:

 

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

public partial class FormViewDemo : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            BindData(0);
        }
    }
    private void BindData(int pageIndex)
    {
        //实例化Connection对象
        SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
        //实例化Command对象
        string sql = "select top 5 * from UserInfo order by UserID desc";
        SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
        DataTable data = new DataTable();
        adapter.Fill(data);

        FormView1.DataSource = data;
        FormView1.PageIndex = pageIndex;
        FormView1.DataBind();
    }
    protected void FormView1_PageIndexChanging(object sender, FormViewPageEventArgs e)
    {
        BindData(e.NewPageIndex);
    }
}
下面是运行效果:

 


 

DetailsView控件

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

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

前台代码如下:

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DetailsViewDemo.aspx.cs" Inherits="DetailsViewDemo" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>DetailsView控件的例子</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:DetailsView ID="DetailsView1" runat="server"  Width="400px" AutoGenerateRows="False">
        <Fields>
                <asp:BoundField DataField="UserId" HeaderText="编号" />
                <asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}"
                    DataTextField="RealName" HeaderText="查看" />
                <asp:BoundField DataField="UserName" HeaderText="用户名" />
                <asp:BoundField DataField="RealName" HeaderText="真实姓名" />
                <asp:BoundField DataField="Age" HeaderText="年龄" />
                <asp:CheckBoxField DataField="Sex" HeaderText="男" />
                <asp:BoundField DataField="Mobile" HeaderText="手机" />
                <asp:TemplateField HeaderText="电子邮件">
                    <AlternatingItemTemplate>
                        <a href='emailto:<%#Eval("Email") %>'>发电子给<%#Eval("RealName") %></a>
                    </AlternatingItemTemplate>
                    <ItemTemplate>
                        <%#Eval("Email") %>
                    </ItemTemplate>
                </asp:TemplateField>
            </Fields>
            <EmptyDataTemplate>
                温馨提示:当前没有任何记录哦。
            </EmptyDataTemplate>
        </asp:DetailsView>
    
    </div>
    </form>
</body>
</html>
后台代码如下:

 

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

public partial class DetailsViewDemo : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            int userId;
            //当当前URL地址中含有"UserId"参数并且能转换成数字时
            if (int.TryParse(Request.QueryString["UserId"], out userId))
            {
                //实例化Connection对象
                SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
                //实例化Command对象
                SqlCommand command = new SqlCommand("select * from UserInfo where UserId=@UserId", connection);
                command.Parameters.AddWithValue("@UserId", userId);//添加Parameter参数
                SqlDataAdapter adapter = new SqlDataAdapter(command);
                DataTable data = new DataTable();
                adapter.Fill(data);

                DetailsView1.DataSource = data;
                DetailsView1.DataBind();
            }
            else
            {
                //如果不能转换成数字,生成一个空DataTable对象来绑定
                //因为我们在设计代码中定义如果没有符合条件的数据时的显示效果
                //所以此时会显示我们定义的没有数据时的效果
                DataTable data = new DataTable();
                DetailsView1.DataSource = data;
                DetailsView1.DataBind();
            }
        }
    }
}
还记得前面使用GridView显示数据的例子吗?我们可以从那里开始,因为在前面的GridView例子中我们定义了一个查看数据详情的超级链接的例子,那里我们还使用了一个HyperLinkField,它的定义如下:

<asp:HyperLinkField DataNavigateUrlFields="UserId" DataNavigateUrlFormatString="ShowUser.aspx?UserId={0}"
                    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留言告诉我,我一定会尽量满足大家的要求。

周公(周金桥)

2008-10-24 01:32


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/txl816/archive/2008/10/27/3158796.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值