7.2 DetailsView控件

在许多情况下,常常需要深入一条记录进行研究,此时DetailsView控件就可以大显身手了。使用DetailsView控件可以逐一显示、分页、更新、插入或删除其关联数据源中的记录,但它不支持排序。因此,它常用于更新和插入新记录,并且通常在主/详细方案中使用。在这些方案中,主控件的选中记录决定了要在DetailsView控件中显示的记录。即使DetailsView控件的数据源公开了多条记录,该控件每次也只会显示一条数据记录。

默认情况下,DetailsView控件将逐行单另显示记录的各个字段。

7.2.1 数据绑定

DetailsView控件的数据绑定方法很简单。可以使用下面两种方法进行数据绑定:

1)使用DataSourceID属性。通过此属性可以将DetailsView控件绑定到数据源控件,例如SqlDataSource控件。当使用DataSourceID属性绑定到数据源时,DetailsView控件支持双向数据绑定。因此,除了可以使该控件显示数据之外,只需要设置相关的属性,还可以使它自动支持对绑定数据的分页、插入、更新和删除操作。如下面的示例所示:


<asp:DetailsView ID="DetailsView1"

DataSourceID="SqlDataSource1"runat="server"

Height="50px"Width="125px">

</asp:DetailsView>

<asp:SqlDataSource ID="SqlDataSource1"

runat="server"ConnectionString="

<%$ConnectionStrings:ASPNET4ConnectionString%>"

SelectCommand="SELECT[employeeid],[employeename],

[department],[address],[email]FROM[Employee]">

</asp:SqlDataSource>


2)使用DataSource属性。此属性允许绑定到各种对象,包括ADO.NET数据集、数据读取器以及内存中的结构(如集合)。如果采用此方法,需要为所有附加功能(如排序、分页和更新)编写相关的代码。如下面的示例所示:


public partial class DetailsViewTest:System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

if(!IsPostBack)

{

Bind();

}

}

private void Bind()

{

DetailsView1.DataSource=

DbHelper.Instance.CreateDataTable(

CommandType.Text,"select*from employee");

DetailsView1.DataBind();

}

}


图7-7展示了一个简单的DetailsView控件数据绑定示例。从中可以看出,DetailsView控件显示的数据包括两部分内容,即字段名称与相对应的值。并且,它每次只能够显示一条数据信息。

figure_0272_0183

图 7-7 DetailsView控件的简单示例

7.2.2 定义字段

在DetailsView控件中,AutoGenerateRows属性的默认值设置为true,它为数据源中某个可绑定类型的每个字段自动生成一个绑定行字段对象,有效的可绑定类型包括String、DateTime、Decimal、Guid以及基元类型集,按其出现在数据源中的顺序,每个字段以文本形式显示在一行中。自动生成行提供了一种显示记录中每个字段的快速简单的方式。

但是,若要使用DetailsView控件的高级功能,就必须得显式声明要包含在DetailsView控件中的行字段。若要声明行字段,首先必须将AutoGenerateRows属性的值设置为false。接着,在DetailsView控件的开始和结束标记之间添加<Fields>开始和</Fields>结束标记。最后,列出想包含在<Fields>开始和</Fields>结束标记之间的行字段。指定的行字段即以所列出的顺序添加到Fields集合中。同样,Fields集合也允许以编程方式管理DetailsView控件中的行字段。

DetailsView控件中的每个数据行是通过声明一个字段控件创建的,所有的字段控件都派生自DataControlField。不同的行字段类型确定控件中各行的行为,表7-3列出了可以使用的不同行字段类型。

figure_0273_0184

下面的示例展示了如何自定义字段:


<asp:DetailsView ID="DetailsView1"AutoGenerateRows="false"

runat="server"Height="50px"Width="125px">

<Fields>

<asp:BoundField DataField="employeeid"HeaderText="编号"/>

<asp:BoundField DataField="employeename"HeaderText="姓名"/>

<asp:BoundField DataField="department"HeaderText="部门"/>

<asp:BoundField DataField="address"HeaderText="地址"/>

<asp:BoundField DataField="email"HeaderText="Email"/>

</Fields>

</asp:DetailsView>


示例运行结果如图7-8所示。

figure_0273_0185

图 7-8 DetailsView控件自定义字段示例运行结果

7.2.3 分页

在DetailsView控件中,可以以分页浏览的形式来逐条查看数据记录。如果是通过它的DataSourceID属性以数据控件(如SqlDataSource)来绑定数据的,那么只需要将DetailsView控件的AllowPaging属性设置为True,便自动打开了分页功能。

但如果是通过它的DataSource属性与DataBind()方法来从后台获取数据源(如DataSet、DataTable)进行绑定的,那么除了需要将DetailsView控件的AllowPaging属性设置为True之外,还需要处理它的PageIndexChanging事件。如下面的示例所示:


<asp:DetailsView ID="DetailsView1"AutoGenerateRows="false"

OnPageIndexChanging="DetailsView1_PageIndexChanging"

AllowPaging="True"

runat="server"Height="50px"Width="125px">

<Fields>

……

</Fields>

</asp:DetailsView>


现在,就可以这样来处理PageIndexChanging事件了。如下面的代码所示:


protected void DetailsView1_PageIndexChanging(object sender,

DetailsViewPageEventArgs e)

{

this.DetailsView1.PageIndex=e.NewPageIndex;

Bind();

}


除此之外,在将AllowPaging属性设置为true时,还可以使用PagerSettings属性来自定义由DetailsView控件生成的分页用户界面((U)的外观。DetailsView控件可以显示允许向前和向后导航的方向控件,以及允许用户移动到特定页的数字控件。可以通过设置Mode属性来自定义分页用户界面模式,可用的模式有NextPrevious、NextPreviousFirstLast、NumericFirstLast与Numeric。如下面的示例所示:


<asp:DetailsView ID="DetailsView1"AutoGenerateRows="false"

OnPageIndexChanging="DetailsView1_PageIndexChanging"

AllowPaging="True"

runat="server"Height="50px"Width="125px">

<Fields>

……

</Fields>

<PagerSettings Mode="NextPreviousFirstLast"

NextPageText="下一页"PreviousPageText="上一页"

FirstPageText="首页"LastPageText="末页"

PageButtonCount="1"Position="Bottom"/>

</asp:DetailsView>


示例运行结果如图7-9所示。

figure_0274_0186

图 7-9 DetailsView控件自定义分页样式示例运行结果

7.2.4 添加、修改和删除

上面已经阐述过,当使用DataSourceID属性绑定到数据源时,DetailsView控件支持双向数据绑定。因此,除了可以使该控件显示数据之外,只需要设置相关的属性还可以使它自动支持对绑定数据的分页、插入、更新和删除操作,即通过将DetailsView控件的AutoGenerateEditButton、AutoGenerateI nsertButton和AutoGenerateDeleteButton属性中的一个或多个设置为true,可以启用DetailsView控件的内置编辑功能。DetailsView控件将自动添加此功能,使用户能够编辑或删除当前绑定的记录以及插入新记录。

但如果是通过它的DataSource属性与DataBind()方法来从后台获取数据源(如DataSet、DataTable)进行绑定的,那么上面的这种方法就不能够用了。这时,可以通过添加处理事件来完成DetailsView控件的数据的编辑处理功能,如删除事件ItemDeleting、修改事件ItemUpdating、插入事件ItemInserting等。表7-4显示了DetailsView控件的常用事件。

figure_0275_0187

下面将通过一个具体的示例,来演示如何使用事件处理程序完成DetailsView控件的添加、修改和删除功能。首先,需要在DetailsView控件中添加相关的事件,如下面的代码所示:


OnModeChanging="DetailsView1_ModeChanging"

OnItemDeleting="DetailsView1_ItemDeleting"

OnItemUpdating="DetailsView1_ItemUpdating"

OnItemInserting="DetailsView1_ItemInserting">


在DetailsView控件中声明完事件之后,还需要在模板列((TmplateField)里面创建相关的编辑模板,如ItemTemplate、InsertItemTemplate、EditItemTemplate模板等。完整代码示例如代码清单7-1所示。

代码清单7-1 DetailsViewTest.aspx


<body>

<form id="form1"runat="server">

<div>

<asp:DetailsView ID="DetailsView1"

AutoGenerateRows="false"DataKeyNames="employeeid"

OnPageIndexChanging="DetailsView1_PageIndexChanging"

AllowPaging="True"runat="server"

Height="50px"Width="425px"

OnModeChanging="DetailsView1_ModeChanging"

OnItemDeleting="DetailsView1_ItemDeleting"

OnItemUpdating="DetailsView1_ItemUpdating"

OnItemInserting="DetailsView1_ItemInserting">

<Fields>

<asp:TemplateField HeaderText="编号">

<ItemTemplate>

<%#Eval("employeeid")%>

</ItemTemplate>

<InsertItemTemplate>

<asp:TextBox ID="txt_insert_employeeid"

runat="server"/>

</InsertItemTemplate>

<EditItemTemplate>

<%#Eval("employeeid")%>

</EditItemTemplate>

</asp:TemplateField>

<asp:TemplateField HeaderText="姓名">

<ItemTemplate>

<%#Eval("employeename")%>

</ItemTemplate>

<InsertItemTemplate>

<asp:TextBox ID="txt_insert_employeename"

runat="server"/>

</InsertItemTemplate>

<EditItemTemplate>

<asp:TextBox ID="txt_edit_employeename"

Text='<%#Eval("employeename")%>'

runat="server"/>

</EditItemTemplate>

</asp:TemplateField>

<asp:TemplateField HeaderText="部门">

<ItemTemplate>

<%#Eval("department")%>

</ItemTemplate>

<InsertItemTemplate>

<asp:TextBox ID="txt_insert_department"

runat="server"/>

</InsertItemTemplate>

<EditItemTemplate>

<asp:TextBox ID="txt_edit_department"

Text='<%#Eval("department")%>'

runat="server"/>

</EditItemTemplate>

</asp:TemplateField>

<asp:TemplateField HeaderText="地址">

<ItemTemplate>

<%#Eval("address")%>

</ItemTemplate>

<InsertItemTemplate>

<asp:TextBox ID="txt_insert_address"

runat="server"/>

</InsertItemTemplate>

<EditItemTemplate>

<asp:TextBox ID="txt_edit_address"

Text='<%#Eval("address")%>'

runat="server"/>

</EditItemTemplate>

</asp:TemplateField>

<asp:TemplateField HeaderText="Email">

<ItemTemplate>

<%#Eval("email")%>

</ItemTemplate>

<InsertItemTemplate>

<asp:TextBox ID="txt_insert_email"

runat="server"/>

</InsertItemTemplate>

<EditItemTemplate>

<asp:TextBox ID="txt_edit_email"

Text='<%#Eval("email")%>'

runat="server"/>

</EditItemTemplate>

</asp:TemplateField>

<asp:TemplateField HeaderText="操作">

<ItemTemplate>

<asp:Button ID="btnEdit"runat="server"

CausesValidation="False"

CommandName="Edit"Text="编辑"/>

<asp:Button ID="btnNew"runat="server"

CausesValidation="False"CommandName="New"

Text="新建"/>

<asp:Button ID="btnDelete"runat="server"

CausesValidation="False"

CommandName="Delete"Text="删除"

OnClientClick="return confirm(

'确定要删除此记录吗?');"/>

</ItemTemplate>

<InsertItemTemplate>

<asp:Button ID="btnInsert"runat="server"

CausesValidation="True"

CommandName="Insert"Text="插入"/>

<asp:Button ID="btnCancel"runat="server"

CausesValidation="False"

CommandName="Cancel"Text="取消"/>

</InsertItemTemplate>

<EditItemTemplate>

<asp:Button ID="btnUpdate"runat="server"

CausesValidation="True"

CommandName="Update"Text="更新"

OnClientClick="return confirm(

'确定要更新此记录吗?');"/>

<asp:Button ID="btnCancel2"runat="server"

CausesValidation="False"

CommandName="Cancel"Text="取消"/>

</EditItemTemplate>

</asp:TemplateField>

</Fields>

<PagerSettings Mode="NextPreviousFirstLast"

NextPageText="下一页"PreviousPageText="上一页"

FirstPageText="首页"LastPageText="末页"

PageButtonCount="1"Position="Bottom"/>

</asp:DetailsView>

</div>

</form>

</body>


接下来,就可以在DetailsViewTest.aspx.cs文件里面编辑相关的事件处理程序来完成添加、修改和删除功能。其处理方法很简单,如下面的代码所示:


public partial class DetailsViewTest:System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

if(!IsPostBack)

{

Bind();

}

private void Bind()

{

DetailsView1.DataSource=

DbHelper.Instance.CreateDataTable(CommandType.Text,

"select*from employee");

DetailsView1.DataBind();

}

protected void DetailsView1_PageIndexChanging(object sender,

DetailsViewPageEventArgs e)

{

this.DetailsView1.PageIndex=e.NewPageIndex;

Bind();

}

protected void DetailsView1_ModeChanging(object sender,

DetailsViewModeEventArgs e)

{

this.DetailsView1.ChangeMode(e.NewMode);

Bind();

}

protected void DetailsView1_ItemDeleting(object sender,

DetailsViewDeleteEventArgs e)

{

DbHelper.Instance.ExecuteNonQuery(CommandType.Text,

"delete from employee where employeeid="

+Convert.ToInt32((tis.DetailsView1.DataKey.Value));

Bind();

}

protected void DetailsView1_ItemUpdating(object sender,

DetailsViewUpdateEventArgs e)

{

DbHelper.Instance.ExecuteNonQuery(CommandType.Text,

"update employee set employeename='"

+(((TxtBox)DetailsView1.FindControl

("txt_edit_employeename")).Text

+"',department='"

+(((TxtBox)DetailsView1.FindControl

("txt_edit_department")).Text

+"',address='"+(((TxtBox)DetailsView1.FindControl

("txt_edit_address")).Text

+"',email='"+(((TxtBox)DetailsView1.FindControl

("txt_edit_email")).Text

+"'where employeeid="+Convert.ToInt32

((tis.DetailsView1.DataKey.Value));

Bind();

}

protected void DetailsView1_ItemInserting(object sender,

DetailsViewInsertEventArgs e)

{

DbHelper.Instance.ExecuteNonQuery(CommandType.Text,

"insert employee(employeeid, employeename,

department, address, email)values("

+(((TxtBox)DetailsView1.FindControl

("txt_insert_employeeid")).Text+",'"

+(((TxtBox)DetailsView1.FindControl

("txt_insert_employeename")).Text+"','"

+(((TxtBox)DetailsView1.FindControl

("txt_insert_department")).Text+"','"

+(((TxtBox)DetailsView1.FindControl

("txt_insert_address")).Text+"','"

+(((TxtBox)DetailsView1.FindControl

("txt_insert_email")).Text+"')");

Bind();

}

}


运行代码清单7-1,运行结果如图7-10与图7-11所示。

figure_0279_0188

图 7-10 带编辑功能的DetailsView控件运行示例

figure_0279_0189

图 7-11 编辑一条记录

7.2.5 样式定义

除此之外,DetailsView控件也提供了丰富的样式属性。可以通过设置DetailsView控件的不同部分的样式属性来自定义该控件的外观,如表7-5所示。

figure_0279_0190

figure_0280_0191

为了演示样式属性的使用方法,下面继续为代码清单7-1中的DetailsView控件添加4个样式属性,即HeaderStyle、RowStyle、AlternatingRowStyle与EditRowStyle样式属性。如下面的代码所示:


<asp:DetailsView ID="DetailsView1"

AutoGenerateRows="false"

DataKeyNames="employeeid"

OnPageIndexChanging="DetailsView1_PageIndexChanging"

AllowPaging="True"runat="server"

Height="50px"Width="425px"

OnModeChanging="DetailsView1_ModeChanging"

OnItemDeleting="DetailsView1_ItemDeleting"

OnItemUpdating="DetailsView1_ItemUpdating"

OnItemInserting="DetailsView1_ItemInserting">

<HeaderStyle BackColor="Navy"ForeColor="White"/>

<RowStyle BackColor="White"/>

<AlternatingRowStyle BackColor="LightGray"/>

<EditRowStyle BackColor="LightCyan"/>

<Fields>

……

</asp:DetailsView>


现在再运行代码清单7-1,其运行结果如图7-12所示。

figure_0280_0192

图 7-12 添加样式后的DetailsView控件运行示例