17Web服务器端控件

Web服务器端控件


Web服务器端控件

ASP.Net提供了两类服务器端控件:Html服务器端控件和Web服务器端控件。由于Web服务器端控件功能更强大,和Windows应用程序的控件使用方法类似,容易学习,因此这里只介绍Web服务器端控件。Web服务器端控件包括如下几大类:基本的ASP.Net服务器端控件、服务器端数据验证控件、数据列表控件(Repeater、DataList、DataGrid)、复杂功能控件。本章介绍这些Web服务器端控件常用的属性、事件和方法,以及用Web服务器端控件编制服务器端动态网页的方法。由于在ASP.Net中数据绑定和Windows应用程序的数据绑定有一些区别,功能有所加强,因此数据绑定也是本章的重点。考虑到本书读者可能是仅学习过C语言和计算机基础的学生,可能对微软的SQL Server数据库系统不熟悉,因此本章例子中使用的数据库是第8章中用ACCESS数据库系统建立的学生信息系统数据库StudentI,该数据库文件的路径为:D:\asp\StudentI.mdb。

10.1  基本的Web服务器端控件

基本的Web服务器端控件包括:Label、TextBox、Button、LinkButton、ImageButton、CheckBox、CheckBoxList、RadioButton、RadioButtonList、Image、HyperLink、Table、TableCell、TableRow、DropDownList、ListBox、Panel。这些控件在网页中用Html语言标记,基本的标记格式为:<asp:控件名称 其它属性 runat=server/>或者<asp:控件名称 其它属性> </runat=server>,其中asp:控件名称、runat=server两项是必须的,表示是Web服务器端控件,由Web服务器解释、运行。其它属性是可选的。Web服务器端控件一些共有的属性如下:

l  id:控件名称,相当于Windows应用程序中控件的Name属性,用来区分不同对象。

l  forecolor:字符颜色,例如forecolor ="red"表示字符的颜色为红色。

l  BackColor:背景色,例如BackColor="white"表示背景的颜色为白色。

l  Enabled:布尔变量,为true表示控件可以使用,为false表示不可用,控件变为灰色。

l  Visible:布尔变量,为true表示控件正常显示,为false表示控件不可见。

l  ToolTip:当鼠标指针停留在控件上时显示的提示文本。

l  Width:获取或设置 Web 服务器控件的宽度。

l  Height:获取或设置 Web 服务器控件的高度。

l  AutoPostBack:布尔变量,指示控件事件是否自动调用在服务器端的事件处理函数。

10.1.1       Label控件

Label控件也叫标签控件,用来显示字符串,如提示信息。用Html标记Label控件的格式为:<asp:Label id="label1" font-size="14" font-bold="true" forecolor="red" Text="显示的字符" runat=server/>,注意属性标记格式为:属性=属性值,属性之间用空格分割。也可采用如下格式:<asp:Label id="Label1" runat=server>标签控件显示的字符串</asp:Label>

Label控件常用的属性如下:

l  Font:该属性指定Label控件显示字体风格。此属性包含若干子属性:font-Bold=true表示为黑体、font-Underline=true表示加下划线、font-Strikeout=true表示加删除线、font-Italic=true表示为斜体、font-Name="字体名字"、font-size="14"为字体大小等。请注意,在C#语句中则要使用如下格式:Label1.Font.Underline=true;

l  Text:Label控件中显示的文本。

10.1.2       TextBox控件

TextBox控件,也叫文本框控件,可用来输入文本。TextBox控件Html标记格式如下:

<asp:TextBox id="textBox1" runat=server></asp:TextBox>

TextBox控件常用的属性和事件如下:

l  属性Text:在TextBox控件中输入的文本。

l  属性TextMode:TextBox控件的模式。TextMode=SingleLine为单行编辑框;TextMode=MultiLine为多行编辑框,可以有滚动条;TextMode=PassWord为口令编辑框。

l  属性MaxLength:TextBox控件中允许输入的最多字符数。

l  属性Rows:TextBox控件为多行编辑框时,该属性有效,表示允许最大行数。

l  事件TextChanged:控件中文本发生变化时产生的事件,例如用户输入内容改变。

10.1.3       Button、LinkButton和ImageButton控件

Button控件为普通按钮,LinkButton控件为超级链接形式的按钮,ImageButton控件为图形按钮。用Html标记这3个按钮控件的格式如下:

<asp:button text="按钮标题" id="btn1" Onclick="Btn_Click" runat=server/>

<asp:LinkButton text="按钮标题" id="btn2" Onclick="Btn_Click" runat=server/>

<asp:ImageButton id="btn3" Onclick="Btn_Click" ImageUrl="t1.bmp" runat="server"/>

请注意定义按钮单击事件处理函数的方法,这3个按钮控件常用的属性和事件如下:

l  属性Text:Button控件是按钮的标题,LinkButton控件是带有下划线的超级链接字符。ImageButton控件无此属性,该控件显示指定图形文件的图形。

l  属性ImageUrl:ImageButton控件图形文件的URL,最好和网页文件放在同一个目录下。

l  事件Click:单击按钮产生的单击(Click)按钮事件,可为单击事件增加事件处理函数。

10.1.4       CheckBox和CheckBoxList控件

CheckBoxList控件中可以包含若干CheckBox多选框控件,可以选中这些多选框中的一个或多个,也可以选中所有多选框或都一个也不选,可用来表示一些可共存的特性,例如一个人的爱好。CheckBoxList控件用如下方法标记:

<asp:CheckBoxList id="checkboxlist1" runat="server">

<asp:ListItem Selected=true>音乐</asp:ListItem>

<asp:ListItem>文学</asp:ListItem>

</asp:CheckBoxList>

CheckBoxList控件常用的属性和事件如下:

l  属性SelectedItem:被选中的索引号最小的CheckBox按钮。参见10.1.6节例子。

l  属性RepeatColumns:获取或设置CheckBoxList 控件中CheckBox多选框显示的列数。

l  属性RepeatDirection:多个CheckBox多选框是垂直还是水平显示。默认值为 Vertical。

l  属性Items:该控件中所有CheckBox控件的集合,Item[i]表示第i+1个CheckBox控件。

l  事件SelectedIndexChanged:被选中的多选框控件索引号改变时,将引发该事件。

CheckBox多选框控件常用的属性和事件如下:

l  属性Selected:为true多选框被选中,否则不被选中。下边例子音乐多选框被选中。

l  属性Text: CheckBox多选框控件的标题。

l  属性Value: CheckBox多选框控件所代表的数值。参见10.1.6节例子。

l  事件CheckedChanged:用户单击多选框控件,选中或不选中状态改变时,引发的事件。

下面例子在窗口中用Label控件显示某人的爱好,有两个CheckBox多选框,一个代表是否爱好音乐,一个代表是否爱好文学,用鼠标单击CheckBox多选框,选中或不选中标题为"音乐"或"文学"多选框,Label控件显示实际所做的选择。网页文件如下:

<html>

<script runat="server" Language="C#" >

 void Check_Clicked(Object sender, EventArgs e)

 {  String s="你的爱好是:";

    for (int i=0; i<checkboxlist1.Items.Count; i++)

    {  if (checkboxlist1.Items[i].Selected)

           s += checkboxlist1.Items[i].Text;

     }

     Message.Text=s;

  }

</script>

<body>

 <form runat="server">

    <asp:CheckBoxList id="checkboxlist1" AutoPostBack="True"

              OnSelectedIndexChanged="Check_Clicked"  runat="server">

       <asp:ListItem>音乐</asp:ListItem>

       <asp:ListItem>文学</asp:ListItem>

    </asp:CheckBoxList>

    <asp:label id="Message" Text="你的爱好是:" runat="server"/>

 </form>

</body>

</html>

用VS.Net集成环境实现具体步骤如下:

(1)创建Web应用程序新项目。放置Label控件到Web窗体,其属性Text="你的爱好是:"。

(2)放置CheckBoxList控件到窗体,单击属性Items右侧标题为"…"的按钮,出现"集合编辑器"对话框。单击"添加"按钮,增加两个CheckBox按钮,属性Text分别为:音乐、文学。由于爱好是可以多选的,因此必须用CheckBox控件。设定属性AutoPostBack=true。

(3)为CheckBoxList控件SelectedIndexChanged事件处理函数增加语句如下:

private void CheckBoxList1_SelectedIndexChanged(object sender,System.EventArgs e)

{   String s="你的爱好是:";

    for(int i=0;i<2;i++)

    {   if(CheckBoxList1.Items[i].Selected)

            s=s+CheckBoxList1.Items[i].Text;

    }

    Label1.Text=s;

}

(4)编译,运行,选中标题为"音乐"的多选框,标签控件显示"你的爱好是:音乐",再选中标题为"文学"的多选框,标签控件显示"你的爱好是:音乐文学"。

10.1.5       RadioButton和RadioButtonList控件

有一些特性是互斥的,例如性别,选择这些特性可用RadioButtonList控件,该控件中可以生成多个RadioButton按钮,但只能选其中一个按钮。该控件用如下方法标记:

<asp: RadioButtonList id=radioButtonList1 runat="server">

<asp:ListItem Selected=true>男</asp:ListItem>

<asp:ListItem>女</asp:ListItem>

</asp:RadioButtonList1>

RadioButtonList控件常用的属性和CheckBoxList控件类似,这就不介绍了。

例子e10_1_5:两个单选按钮,标题分别为男和女,初始标题为"男"的单选按钮被选中。用Label控件显示选择的结果。网页文件如下:

<html>

<script language="C#" runat="server">

    void Check_Clicked(Object sender, EventArgs e)

    {  if(RadioButtonList1.SelectedIndex==0)

            Label1.Text="男";

       else

            Label1.Text="女";  

    }

</script>

<body>

    <form runat=server>

        <asp:RadioButtonList id=RadioButtonList1 AutoPostBack="True"

           OnSelectedIndexChanged="Check_Clicked"  runat="server">

              <asp:ListItem Selected=true>男</asp:ListItem>

              <asp:ListItem>女</asp:ListItem>

        </asp:RadioButtonList>

        <asp:Label id=Label1  Text="男" runat="server"/>

    </form>

  </body>

</html>

用VS.Net实现的具体步骤如下:

(1) 创建Web应用程序新项目。放置Label控件到Web窗体,属性Text="男"。

(2) 放置RadioButtonList控件到窗体,单击属性Items右侧标题为"…"的按钮,出现"集合编辑器"对话框。单击"添加"按钮,增加1个RadioButton按钮,属性Text为"男", Selected属性为true。增加另一个RadioButton按钮,Text属性为"女",Selected属性为false。属性AutoPostBack=true。

(3) 为RadioButtonList控件SelectedIndexChanged事件增加事件处理函数如下:

private void RadioButtonList1_SelectedIndexChanged

(object sender,System.EventArgs e)

{   if(RadioButtonList1.SelectedIndex==0)

       Label1.Text="男";

    else

        Label1.Text="女";

}

(4) 编译,运行,分别单击RadioButtonList中的两个RadioButton按钮,标签控件显示所作的选择。请想一想和CheckBox多选框的区别。

10.1.6       Image控件

Image控件用来在网页中显示一幅图像,该控件的Html标记格式如下:

<asp:Image id="Image1" runat="server" ImageUrl="images/image1.jpg"/>

Image控件常用的属性如下:

l  AlternateText:字符串类型,如果图像不被正确显示,则显示此字符串。

l  ImageAlign:图像对齐方式。

l  ImageUrl:显示在网页中的图像文件的URL地址。

例子e10_1_6:该例有2个单选按钮,根据单选按钮哪个被选中,显示不同的图像。用VS.Net实现的具体步骤如下:

(1) 创建Web应用程序新项目。放置Image控件到窗体,属性id= Image1。

(2) 放置RadioButtonList控件到窗体。单击属性Items后标题为"…"的按钮,出现"集合编辑器"对话框,单击"添加"按钮,增加一个RadioButton按钮,Text属性"图1",Value属性为"p1.jpg",Selected属性为true。增加另一个RadioButton按钮,Text属性为"图2",Value属性为"p2.jpg",Selected属性为false。属性AutoPostBack=true。

(3) 为RadioButtonList控件的SelectedIndexChanged事件增加事件函数如下:

private void RadioButtonList1_SelectedIndexChanged

(object sender,System.EventArgs e)

{   Image1.ImageUrl=RadioButtonList1.SelectedItem.Value;

}

(4) 为Page_Load事件处理函数增加语句:

private void Page_Load(object sender, System.EventArgs e)

{   Image1.ImageUrl=RadioButtonList1.Items[0].Value;

}

(5) 编译,运行,分别单击RadioButtonList中的两个RadioButton按钮,将显示不同图像。

10.1.7       HyperLink控件

HyperLink控件是超级链接控件,用来从一个网页跳转到另一个网页。用如下方法标记:

<asp:HyperLink id="hyperlink1" ImageUrl="images/pict.jpg" Target="_new"

    NavigateUrl="http://www.microsoft.com" Text="微软"  runat="server"/>

HyperLink控件常用的属性如下:

l  Text:设置的超级链接的文字。

l  ImageUrl:也可以使用图形完成超级链接,ImageUrl为控件显示图像文件的URL。

l  NavigateUrl:超级链接到另一个网页的URL。

l  Target:表示打开的网页的位置。为_blank,在一个没有框架的新窗口打开新网页;为_self,在原窗口打开,为_parent在父窗口打开。

10.1.8       Table、TableCell和TableRow控件

使用这3个控件可以在网页中建立一个表,使用方法如下:

<asp:Table id="Table1" runat="server" CellPadding=10 GridLines="Both">

    <asp:TableRow>

       <asp:TableCell>第0行,第0列</asp:TableCell>

       <asp:TableCell>第0行,第1列</asp:TableCell>

    </asp:TableRow>

    <asp:TableRow>

       <asp:TableCell>第1行,第0列</asp:TableCell>

       <asp:TableCell>第1行,第1列</asp:TableCell>

    </asp:TableRow>

 </asp:Table>

    Table控件常用的属性如下:

l  BackImageUrl:背景图像文件的URL。

l  CellPadding:列字符和列边框之间的间隔(以像素为单位)。默认值为 -1,表示还未设置该属性。

l  CellSpacing:列和列之间的间隔(以像素为单位)。默认值为 -1,表示还未设置该属性。

l  GridLines:指定Table控件的网格线型。为None不显示网格线;为Horizontal仅显示水平网格线。为Vertical仅显示垂直网格线;为Both 同时显示水平和垂直网格线。

l  HorizontalAlign:表的每个单元格中的文字的水平对齐方式。为NotSet,表示尚未设置水平对齐方式;为Left,表示左对齐;为Center,表示居中对齐;为Right表示右对齐。为Justify 表示同时与页面的左右页边对齐。

该控件不支持数据绑定,在很多情况下,用DataList 或 DataGrid 控件可完成同样功能, Table类主要由控件开发人员使用。用VS.Net创建表格的具体步骤如下:

(1)    创建Web应用程序项目。放置Table控件到窗体,单击属性Row右侧标题为"…"的按钮,出现"选择TableRow集合编辑器"对话框,单击"添加"按钮,增加两行(TableRow对象)。

(2)    选择索引号为0的TableRow,单击属性Cell右侧标题为"…"的按钮,出现"选择TableCell集合编辑器"对话框,单击"添加"按钮,增加三列。修改每列的属性Text,分别为:课程总论、刚体静力学、弹性静力学。

(3)    选择引号为1的TableRow,用同样的方法增加三列。修改每列的Text属性,分别为:数据结构、计算机组成原理、操作系统。

(4)    运行后,可以看到两行三列的表。

10.1.9       DropDownList控件

DropDownList控件是一个下拉列表文本框控件。控件Html标记格式如下:

<asp:DropDownList id="dropDownList1" AutoPostBack="True" runat="server"

OnSelectedIndexChanged="Selection_Change">

<asp:ListItem Selected="True" Value="White">白色</asp:ListItem>

    <asp:ListItem Value="Black">黑色</asp:ListItem>

</asp:DropDownList>

    DropDownList控件常用的属性和事件如下:

l  属性SelectedIndex:从下拉列表中选定项的索引。默认值为0,选择下拉列表第1项。

l  属性SelectedItem:控件中的选定项。例如上边的例中,标题为"白色"的项被选中,则有:SelectedItem.Text="白色";SelectedItem.Value="White"。

l  事件OnSelectedIndexChanged:选定项被改变时产生的事件。

用记事本程序生成网页的例子可参考例子e10_3_1。下例用VS.Net创建,该例增加一个DropDownList控件用来选择课程,标签控件显示所做的选择,具体步骤如下:

(1)      创建Web应用程序新项目。放置DropDownList控件到窗体。单击属性Items右侧标题为"…"的按钮,出现"选择ListItem集合编辑器"对话框,单击添加按钮,增加三项。修改每项的Text属性分别为:课程总论、刚体静力学、弹性静力学。

(2)      放工具箱的Label控件到窗体,id=label1。

(3)      放置Button控件到窗体,增加单击按钮事件处理函数如下:

private void Button1_Click(object sender, System.EventArgs e)

{   label1.Text=DropDownList1.SelectedItem.Text;

}

(4)      运行,从下拉列表选择"刚体静力学",单击按钮控件,标签控件显示"刚体静力学"。

10.1.10    ListBox控件

ListBox列表控件的Html标记格式如下:

<asp:ListBox id="listBox1" Rows="6" SelectionMode="Single" runat="server">

<asp:ListItem Selected="True" Value="White">白色</asp:ListItem>

    <asp:ListItem Value="Black">黑色</asp:ListItem>

</asp:ListBox>

ListBox控件常用的属性、事件和DropDownList控件基本一致,不相同的如下:

l  SelectionMode:指定控件的选择模式。为Multiple允许多选,为Single只能单选。

l  SelectedValue:等价于SelectedItem.Value。如果未选定任何项,返回空字符串("")。

l  Rows:获取或设置 ListBox 控件中显示的行数。

请读者把10.1.9节中的例子中DropDownList控件改为ListBox 控件。

10.2  数据验证控件

用户输入了数据,在提交前,首先要验证输入的数据是否正确。当然,可以自己编程序进行验证。ASP.Net提供了一些验证控件,可以不用编制验证程序完成对输入数据的验证。本节介绍如何使用这些数据验证控件。

10.2.1       数据验证概述

对用户输入的数据进行验证,可以在客户端进行。实现原理是当用户输入了信息并单击提交按钮后,用在客户端运行的JavaScript脚本或VBScript脚本对数据验证,只有所有数据都正确,才发送数据到服务器端处理。此种方法的优点是程序运行在客户端,因此反应速度快,减轻了服务器和网络的负载。缺点是由于JavaScript脚本或VBScript脚本是以明文的方式嵌入在HTML文档中,客户端可以看到这些脚本程序,如果用户把这段脚本删除,网页也就失去了验证功能,因此这种方法是不安全的。

另一种数据验证方法是在服务器端进行,当用户输入了数据并单击提交按钮后,把数据立刻发送到服务器端,用服务器端程序验证数据的正确性,如果验证不通过,返回错误信息。这种方法虽然响应速度比较慢,增加了服务器的负担,但可靠性上要强很多。

ASP.Net提供了一些验证控件,可以不用编程完成在浏览器端或服务器端对输入数据进行必要的验证。在浏览器端的验证采用JavaScript脚本语言,这些代码被保存到网站宿主目录下的aspnet_client文件夹中。如果修改了宿主目录,请把aspnet_client文件夹拷贝到修改后的宿主目录中。ASP.Net提供如下一些验证控件:

l  RequiredFieldValidator:该验证控件检查是否输入了必须输入的数据。

l  CustomValidator:自定义数据验证规则的验证控件。

l  CompareValidator:对两个控件输入的值进行比较的验证控件。

l  RegularExpressionValidator:正则表达式验证控件。

l  ValidationSummary:集中显示验证错误信息的验证控件。

所有这些验证控件的共有的常用属性如下:

l  属性ControlToValidate:被验证控件(可以是文本框,单选按钮或多选框等控件)的id值。

l  属性ErrorMessage:验证不通过时,显示在控件放置处和ValidationSummary控件中的错误提示信息。如果设置了Text属性,将只在ValidationSummary控件中显示。

l  属性Text:显示在控件放置处的验证提示信息,显示方式由属性Display设定。

l  属性Display:决定属性Text的显示方式,为None,无提示信息;为Static,总是显示提示信息;为Dynamic,发生错误时显示提示信息。

l  属性IsValid:为True,验证通过,否则不通过。网页也有此属性:Page.IsValid,只有本网页中所有验证控件的验证都通过,Page.IsValid才为true。

10.2.2       RequiredFieldValidator控件

数据可以用文本框,单选按钮或多选框等控件输入,如果要求用户必须输入指定数据,可以用控件RequiredFieldValidator对这些控件输入的数据进行验证,检查用户是否输入了必须输入的数据,如果没有输入,则显示提示信息。本控件用html标记的格式如下:

<asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server" Text="错误提示信息"

ErrorMessage="错误提示信息"  ControlToValidate="被验证的控件的id值"

Display="None或Static或Dynamic"/>

下边是一个使用RequiredFieldValidator验证控件的简单例子。本例用户用编辑控件TextBox1输入姓名,要求必须输入数据。用控件RequiredFieldValidator对TextBox1控件输入的数据进行验证,检查用户是否输入了数据,因此属性ControlToValidate=TextBox1。当单击提交按钮后,如果用户没有输入姓名,则用"必须输入姓名"提示用户。

<html>

<body>

<form id="Form1" method="post" runat="server">

姓名:<asp:TextBox id="TextBox1" runat="server"/><br>

<asp:Button Text="提交" runat=server/><br>

<asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server"

ErrorMessage="必须输入姓名" ControlToValidate="TextBox1" Display="Dynamic"/>

</form>

</body>

</html>

上边介绍了用记事本编辑网页时如何使用此控件,下边是用VS.Net编辑网页使用该控件的例子。该例增加一个RadioList控件,选择卡的类型,增加一个编辑控件,输入卡的编号,两者都要求必须输入,用两个RequiredFieldValidator控件验证。步骤如下:

(1)    创建Web应用程序新项目。放置Label控件到窗体,属性Text="RequiredFieldValidator控件的使用"。放置Label控件到窗体,属性Text="输入卡类型:"。

(2)    放置RadioButtonList控件到窗体,属性id=RadioButtonList1。单击属性Items右侧标题为"…"的按钮,出现"集合编辑器"对话框。单击"添加"按钮,增加两个RadioButton按钮,Text属性分别为"苹果卡"、"橡胶卡",Selected属性都为false。

(3)    放置Label控件到窗体,属性Text= "输入卡编号"。

(4)    放置TextBox控件到窗体,属性id=TextBox1。

(5)    放置RequiredFieldValidator控件到窗体,属性ControlToValidate= RadioButtonList1, 属性ErrorMessage="必须输入卡类型",属性Text="请输入卡类型"。属性Display=Dynamic。

(6)    放置RequiredFieldValidator控件到窗体, 属性ControlToValidate=TextBox1, 属性ErrorMessage="必须输入卡编号"。属性Display=Static。

(7)    当用户提交了数据后,所有验证控件对数据进行验证,如果没有错误,自动设置Page.IsValid=true,否则=false。放置Button控件到窗体,属性Text="提交",为按钮增加单击事件处理函数如下:

private void Button1_Click(object sender, System.EventArgs e)

{   if(Page.IsValid==true)

        Label1.Text="已输入了数据";

    else

        Label1.Text="至少有一项未输入数据";

}

(8)    把C:\inetpub\wwwroot\aspnet_client拷贝到D:\Asp文件夹下。运行,如果不输入卡编号,单击标题为"提交"按钮,显示效果如图10.2.3,注意,图中增加了ValidationSummary控件,本例没有使用这个验证控件。

10.2.3       ValidationSummary控件

如果希望在固定位置显示所有验证控件的提示信息,可以在页面中放置控件ValidationSummary,它将自动显示发现错误的数据验证控件的属性ErrorMessage的内容。控件用如下格式标记:

<asp:ValidationSummary id="ValidationSummary1" runat="server"

HeaderText="标题"  DisplayMode="BulletList(默认值)或List或SingleParagraph"

ShowSummary="true或false"> </asp:ValidationSummary>

                        其中,属性DisplayMode的值为BulletList,列表显示每个控件的属性ErrorMessage的错误提示信息,每个提示信息占一行,每行前有一个圆点;为List,显示效果和BulletList基本一致,但每行前无圆点;为SingleParagraph,显示错误提示信息在一行中,如图10.2.3所示。属性ShowSummary决定是否显示错误信息。请读者在上节使用VS.Net的例子中的最后一步,增加一个ValidationSummary控件,修改属性HeaderText="标题",修改属性DisplayMode为SingleParagraph。运行后,如果不输入卡编号,单击标题为"提交"按钮,显示效果如图10.2.3。                     图10.2.3

10.2.4       自定义数据验证控件CustomValidator

CustomValidator控件允许编程者自己定义一个函数对数据进行验证。控件定义如下:

<asp: CustomValidator id="CustomValidator1" runat="server" Text="错误提示信息"

ErrorMessage="错误提示信息"  ControlToValidate="被验证的控件的id值"

Display="None或Static或Dynamic" ClientValidationFunction="浏览器端验证函数名"

OnServerValidate="服务器端验证函数名" />

一般数据验证分为浏览器端验证和服务器端验证,因此,编程者要根据在哪一端验证,编写不同的函数。如果仅在服务器端验证,属性OnServerValidate为编写的服务器端验证函数名,而属性ClientValidationFunction不设定任何值。如在浏览器端验证,在创建浏览器端验证函数时,一定要同时创建服务器端验证函数,否则恶意代码就有可能使验证通过。

例子e10_2_4:本例请用户输入密码,用CustomValidator控件在浏览器端验证,由于在浏览器端验证函数中出现了密码,因此本例采用浏览器端验证是不合适的,这里只是为说明如何实现浏览器端验证。运行效果如下图。网页文件如下:

<html>

<script runat=server  Language="C#">

      void Button1_OnClick(object sender, EventArgs e)

      {  if (Page.IsValid)

            label1.Text = "密码通过";

         else

            label1.Text ="密码不通过";

      }

      void ServerValidate(object source, ServerValidateEventArgs args)

      {  if(args.Value=="12345")

            args.IsValid = true;

         else

            args.IsValid = false;

      }

</script>

<script language="vbscript">

      Sub ClientValidate(source, arguments)

          if (arguments.Value="12345") Then

              arguments.IsValid=true

           else

            arguments.IsValid=false

         end If

         end Sub

</script>

<body>

<form runat="server"> 

        <asp:Label id=label1 runat="server" Text="键入密码" /><br>

        <asp:TextBox id="Text1" runat="server" /><br>

<asp:CustomValidator id="CustomValidator1" ControlToValidate="Text1"

runat="server" ErrorMessage="密码错误!" OnServerValidate="ServerValidate"

ClientValidationFunction="ClientValidate" /><br>

        <asp:Button id="Button1" Text="提交" OnClick="Button1_OnClick" runat="server"/>

      </form>

</body>

</html>

用VS.Net实现上例,这里只用服务器端验证,具体步骤如下:

(1)创建Web应用程序新项目。放置Label控件到窗体,属性Text="键入密码"。

(2)放置TextBox控件到窗体, 属性id=TextBox1,属性Text=""。

(3)放置CustomValidator控件到窗体,属性id=CustomValidator1,属性ControlToValidate为TextBox1, 属性ErrorMessage="密码错误!"。

(4)放置Button控件到窗体,为其增加单击事件处理函数如下:

void Button1_OnClick(object sender, EventArgs e)

{  if (Page.IsValid)

      label1.Text = "密码通过";

   else

      label1.Text ="密码不通过";

}

(5)为CustomValidator控件ServerValidate事件增加事件函数如下:

private void CustomValidator1_ServerValidate(object source,

System.Web.UI.WebControls.ServerValidateEventArgs args)

{   if(args.Value=="12345")

       args.IsValid = true;

     else

       args.IsValid = false;

}

(6)运行,输入正确密码和不正确密码,看一下运行效果。如果不输入任何信息,也能验证通过,因此,必须用控件RequiredFieldValidator检查用户是否输入了密码。

10.2.5       CompareValidator控件

CompareValidator控件可以对两个控件输入的值进行比较。控件Html标记格式如下:

<asp: CompareValidator id="CompareValidator1" runat="server" Text="错误提示信息"

ErrorMessage="错误提示信息"  ControlToValidate="被验证控件的id值"

Display="None或Static或Dynamic"  ValueToCompare="与被验证控件比较的的值"

ControlToCompare="与被验证控件比较的控件的id值" Type="要比较的数据类型"

Operator="比较运算符"/>

其中,属性Type为比较的数据类型,可以是Currency、Date、Time、Double、Integer、String等。属性Operator为比较运算符,可以是:Equal、NotEqual、GreatThan、LessThan、GreatThanEqual、LessThanEqual。比较2个文本框输入,用VS.Net实现的步骤如下:

(1)    新建一个Web应用程序项目。放三个Label控件到窗体,其属性Text分别为"要比较的第1个数"、"要比较的第2个数"、"比较结果"。id分别为Label1、Label2、label3。

(2)    在Label1和Label2控件后,分别放置TextBox控件,id分别为TextBox1和TextBox2。

(3)    放置CompareValidator控件到窗体, id=Compare1,属性ControlToValidate=TextBox1,属性ControlToCompare=TextBox2,属性ErrorMessage="比较结果不正确"。

(4)    放置ListBox控件到窗体,id为ListOperator。单击属性Items右侧标题为"…"的按钮,在"ListItem编辑器"对话框中单击"添加"按钮,增加6项,属性Text分别为:Equal、NotEqual、GreatrThan、GreatrThanEqual、LessThan、LessThanEqual。

(5)    放置ListBox控件到窗体,id为ListType。单击属性Items右侧标题为"…"的按钮,在"ListItem编辑器"对话框中单击"添加"按钮,增加5项,属性Text分别为:String、Integer、Double、Date、Currency。

(6)    设置两个ListBox控件属性SelectionMode为Single,不允许多选。

(7)    设置两个ListBox控件属性AutoPostBack=true。

(8)    为ListOperator控件的事件SelectedIndexChenged增加事件处理函数如下:

private void ListOperator_SelectedIndexChanged(object sender, System.EventArgs e)

{   Compare1.Operator=(ValidationCompareOperator)ListOperator.SelectedIndex;

    Compare1.Validate();//对被验证的输入控件执行验证并更新IsValid 属性。

}

(9)    为ListType控件的事件SelectedIndexChenged增加事件处理函数如下:

private void ListType_SelectedIndexChanged(object sender, System.EventArgs e)

{   Compare1.Type=(ValidationDataType)ListType.SelectedIndex;

    Compare1.Validate();

}

(10) 放置Button控件到窗体,为按钮控件增加单击事件处理函数如下:

private void Button1_Click(object sender, System.EventArgs e)

{   if(Page.IsValid==true)

        label3.Text="数据验证正确";

    else

        label3.Text="数据验证不正确";

}

(11) 运行,ListOperator列表框中选择Equal,ListType列表框中选择String,在两个编辑框中分别输入相同或不相同的字符串,单击按钮,看一下效果。

10.2.6       RangeValidator控件

RangeValidator控件检查被验证控件输入的值是否在指定范围内。控件标记格式如下:

<asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server" Text="错误提示信息"

ErrorMessage="错误提示信息"  ControlToValidate="被验证控件的id值"

Display="None或Static或Dynamic" MinimumValue="允许的最小值"

MaximumValue="允许的最大值" Type="要比较值的数据类型" />

其中MinimumValue和MaximumValue属性指定允许输入的最大值和最小值。Type 属性用于指定要比较值的数据类型。在执行验证操作之前,要比较的值被转换为此数据类型。可以进行比较的数据类型是: String、Integer、Double、Date、Currency。

下面的示例说明如何在 Web 页上增加RangeValidator 控件,以检查文本框控件中输入的数值是否在指定范围内。运行效果如右图。

<html>

  <script runat="server" Language="C#">

    void ButtonClick(Object sender, EventArgs e)

      {  if (Page.IsValid)

            Label1.Text="数有效!";

         else

            Label1.Text="数无效!";

      }

  </script>

<body>

   <form runat="server">

      <asp:Label id="Label1" runat="server">

键入一个1到10的数:</asp:Label> <br>

 <asp:TextBox id="TextBox1" runat="server"/> <br>

      <asp:RangeValidator id="Range1" ControlToValidate="TextBox1"

           MinimumValue="1" MaximumValue="10" Type="Integer" runat="server"

           EnableClientScript="false" Text="必须键入一个1到10的数!" /> <br>

      <asp:Button id="Button1" Text="提交" OnClick="ButtonClick" runat="server"/>

   </form>

</body>

</html>

10.2.7       RegularExpressionValidator控件

RegularExpressionValidator控件也叫正则表达式验证控件,该控件用来检查被验证控件输入的数据是否匹配指定的验证正则表达式。这类验证允许您检查可预知的字符序列,比如身份证号码、电子邮件地址、电话号码和邮编中的字符序列。本控件定义如下:

<asp: RegularExpressionValidator id="RegularExpressionValidator1" runat="server"

Text="错误提示信息" ErrorMessage="错误提示信息"

ControlToValidate="被验证的控件的id值" Display="None或Static或Dynamic"

ValidationExpression="验证正则表达式" />

本控件依据正则表达式进行验证,因此首先讲解一些正则表达式的基本知识,然后介绍如何使用正则表达式验证控件。正则表达式是由普通字符(例如a-z)和特殊字符组成的字符串模板,用这个字符模板与所要验证的字符串进行比较,查看是否匹配,若匹配则通过验证。

1. 正则表达式中的普通字符

正则表达式中包括一些要求匹配的普通字符,普通字符包括可打印字符和不可打印字符两种。打印字符包含a-z、A-Z、0-9以及所有标点符号。常用的不可打印字符意义如下:

l  \n、\r、\f、\t、\v:分别匹配换行符、回车符、换页符、制表符、垂直制表符。

l  \s:匹配任何空白字符,可以是空格、换行符、回车符、换页符、制表符。等价于[\f\n\r\t\v]。

l  \S:匹配任何非空白字符。等价于[^\f\n\r\t\v]。不包括\n、\r、\f、\t、\v的其它任意字符。

l  \w:匹配任何单词字符,可以是字母、数字和下划线等字符。等价于[a-zA-Z0-9_]。

l  \W:匹配任何非单词字符,不包括字母、数字和下划线的其它字符。即[^a-zA-Z0-9_]。

l  \b:匹配单词的结尾,例如:正则表达式"ve\b"匹配"have",但不匹配"very"。

l  \B:匹配单词的开头,例如:正则表达式"ve\B"匹配"very",但不匹配"have"。

l  \d:匹配一个数字字符,等价于[0-9]。例如:"bc\dd"匹配"bc2d"、"bc9d"等,不匹配"bcad"。

l  \D:匹配一个非数字字符,等价于[^0-9]。例如:"bc\Dde"匹配"bcade",不匹配"bc2de"。

2. 正则表达式中的特殊字符

正则表达式中包括一些特殊字符,特殊字符在正则表达式中表示匹配的一些特殊的含义。正则表达式中要匹配这些特殊字符,例如要匹配字符*,必须使用格式:\*。

l  ^:头匹配字符,例如正则表达式"^ab"和"abxyZ"是匹配的,和"xyZab"是不匹配的。

l  $:尾匹配字符,例如:正则表达式"ab$"和"xyab"是匹配的,和"abxy"是不匹配的。

l  *:例如"ab*c"表示在"b*"处可以没有或有多个b,因此和"ac"、"abc"、"abbc"匹配。

l  +:例如ab+c表示在b+处可以有1个或多个b,因此和"abc"、"abbc"、"abbbc"匹配。

.:匹配除换行符(\n)之外的所有字符,例如:(.)+表示不包括换行符的任意字符串。

l  ?:例如"\-?1"表示在"\-?"处可以没有或有1个问号前的字符,即可以为1或-1。

l  |:例如"abc|xyz"和"abc"或"xyz"匹配,"ab(c|x)yz"和"abcyz"或"abxyz"匹配。

l  {n}:匹配n次,n为非负整数。例如"a{2}"和"aa"匹配,和"a"、"aaa"、"ab"不匹配。

l  {n,}:至少匹配n次(n为非负整数)。例如"a{2,}"和"aa"、"aaa"匹配,和"a"、"ab"不匹配。

l  {m,n}:匹配m到n次,m和n为非负整数。例如"a{2,3}"和"aa"、"aaa"匹配。

l  [若干字符]:例如[ACab],表示只能是以下字符:"A"、"C"、"a"、"b"。

l  [^若干字符]:当在方括号里使用^时,它表示"非"或"排除"的意思,常常用来剔除某些字符。例如:[^ACab],表示不是"A"、"C"、"a"、"b"字符的其它字符,符合匹配要求。

l  [a-z]和[A-Z]:[a-z]匹配所有的小写字母。[A-Z]匹配所有的大写字母。[a-zA-Z]匹配所有字母。[0-9]匹配所有的数字。[0-9\.\-] 匹配所有的数字,句号和减号。

l  [^m-o]:匹配所有不包括"m"、"n"、"o"字符的字符。

3. 正则表达式中的优先级

优先级分为4级,按优先级顺序运算,同级优先级从左到右运算。最高优先级:\;2级优先级:()、[];3级优先级:*、+、?、{n}、{n,}、{m,n};最低级:^、$。

下面是常用的一些正则表达式:

l  "^[0-9]*$"只能输入数字。"^\d{5}$"只能输入5位数字。

l  "^\d{2,}$"只能输入至少2位数字。"^\d{2,5}$"只能输入2位到5位数字。

l  "^(0|[1-9][0-9]*)$"只能输入0或非0开头的数字。

l  "^[0-9]+(.[0-9]{1,3})?$"只能输入有1位到3位小数的正实数。

l  "^\+?[1-9][0-9]*$"只能输入非0正整数。"^\-?[1-9][0-9]*$"只能输入非0整数。

l  "^.{3}$"匹配非换行符的3个字符。"^[A-Za-z]+$" "匹配由26个字母组成的字符串。

l  "^12xY$"只能匹配字符串"12xY"。"^[A-Za-z]\w{5,7}$"只能输入由26个字母开头,仅包含字符、数字、下划线,长度为6到8位组成的字符串。

l  "^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"验证E_Mail地址。

l  "^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$"验证因特网URL。

l  "^(\(\d{3,4}\)|\d{3,4}-)?\d{7,8}$"验证电话号码。

l  "^\d{15}|\d{18}$"验证15位获18位身份证号。

下例说明如何使用 RegularExpressionValidator验证一个6位数的邮编。

<html>

     <script runat="server" Language="C#">

       void ValidateBtn_Click(Object sender, EventArgs e)

       {  if (Page.IsValid)

             label1.Text="数据有效!";

          else

             label1.Text="数据无效!";

       }

</script>

<body>

       <form runat="server">

         <asp:Label ID="label1" runat="server">

键入邮政编码</asp:Label><br>

         <asp:TextBox id="TextBox1" runat="server"/> <br>

         <asp:RegularExpressionValidator id="RegularExpressionValidator1"

              ControlToValidate="TextBox1" ValidationExpression="\d{6}"

Display="Static" ErrorMessage="邮政编码必须6位"

EnableClientScript="False" runat="server"/> <br>

         <asp:Button text="提交" OnClick="ValidateBtn_Click" runat=server />

       </form>

     </body>

 </html>

如用VS.Net实现,只需修改属性ValidationExpress即可。

10.3  Web服务器端控件数据绑定

所谓数据绑定技术是把数据集的某个或某些数据与控件的某些能够显示的属性绑定在一起的技术,这些控件可以是Label控件、ListBox控件、DataGrid控件等,当这些控件完成数据绑定后,这些被绑定的属性显示的值将随着数据集中被绑定的数据变化而变化。

ASP.Net引入了新的数据绑定语法。这种语法不仅允许控件属性绑定到DataTable、DataView;还可以绑定到实现了Icollection接口的集合,例如ArrayList、数组、哈希表、堆栈、队列;甚至可以绑定到其它简单属性、表达式和方法调用返回的结果。

10.3.1 绑定到其它控件属性

DataBind是页和所有服务器控件都有的方法。当需要更新被绑定的数据时,必须调用此方法。当在父控件上调用DataBind方法时,该控件的所有子控件也同时调用自己的DataBind方法。例如,在调用页的DataBind方法,既Page.DataBind()会导致调用页上的所有控件的DataBind方法,更新页上所有绑定数据。下面的示例说明如何将一个服务器控件的属性绑定到另一个服务器控件的属性。

<html>

<script language="C#" runat="server">

       void SubmitBtn_Click(Object sender, EventArgs e)

       {    Page.DataBind();//更新页内所有控件中被绑定的数据

       }

    </script>

<body>

      <h3>一个服务器控件的属性绑定到另一个服务器控件的属性</h3>

      <form runat=server>

        <asp:DropDownList id="StateList" runat="server">

            <asp:ListItem>课程总论</asp:ListItem>

            <asp:ListItem>刚体静力学</asp:ListItem>

            <asp:ListItem>弹性静力学</asp:ListItem>

        </asp:DropDownList><BR>

        <asp:button Text="提交" OnClick="SubmitBtn_Click" runat=server/><BR>

        选定的课程:

<asp:label text='<%#StateList.SelectedItem.Text%>' runat=server/>

    </form>

</body>

</html>

网页中语句text='<%# StateList.SelectedItem.Text %>'是将Label控件的Text属性绑定到DropDownList控件的属性StateList.SelectedItem.Text。符号%#表示数据绑定。按钮单击事件处理函数SubmitBtn_Click中的语句Page.DataBind()更新页内的所有被绑定的数据。因此如果从下拉列表中选中某课程,单击按钮,标签控件显示所作的选择。使用VS.Net实现上例的具体步骤如下:

(1)  新建Web应用程序项目。放DrowDownList控件到窗体。单击属性Items右侧标题为"…"的按钮,出现"选择ListItem集合编辑器"对话框,单击"添加"按钮,为控件下拉列表增加三项。修改每项的属性Text,分别为:课程总论、刚体静力学、弹性静力学。

(2)  放Button控件到窗体,单击按钮事件处理函数如下:

private void Button1_Click(object sender, System.EventArgs e)

{   Page.DataBind();}

(3)  放Label控件到窗体,id为Label1。单击属性DataBinding右侧标题为"…"的按钮,打开"Label1数据绑定"对话框,选中"自定义绑定表达式(c)"单选按钮,在单选按钮下边编辑框中输入:DropDownList1.SelectedItem.Text。单击"确定"按钮退出对话框。

(4)  运行,从下拉列表中选中某课程,单击按钮,标签控件显示所选的课程。

10.3.2 绑定到变量

ASP.Net 数据绑定语法支持绑定到公共变量、页的属性和页上其他控件的属性。下面的示例说明如何绑定到变量和页上的简单属性。注意这些值在DataBind()调用前初始化。

<html>

<script language="C#" runat="server">

void Page_Load(Object sender, EventArgs e)

{     Page.DataBind(); }

        string custID="张三";//变量

        int orderCount//页属性

{   get

{   return 11;}

        }

    </script>

<body>

    <h3>页属性和公共变量的数据绑定</h3>

    <form runat=server>

        绑定到公共变量:<%#custID%><br>

        绑定到属性:<%#orderCount%>

    </form>

</body>

</html>

10.3.3 绑定到函数返回值

下例说明如何绑定到函数返回值。在编辑框中输入数字,单击按钮判断该数的奇偶。

<html>

  <script language="C#" runat="server">

    void EnterBtn_Click (Object src,EventArgs e)//按钮单击事件处理函数

{  Page.DataBind();}//更新绑定数据,调用方法EvenOrOdd,标签显示返回值

  String EvenOrOdd(string s)

       {   int number=Convert.ToInt16(s);

if((number%2)==0)

               return "偶数";

            else

               return "奇数";

        }

    </script>

<body>

      <h3>绑定到函数返回值</h3>

      <form runat=server>

        <asp:TextBox id="textBox1" Text="1" runat=server/><br>

<asp:Label Text=<%# EvenOrOdd(textBox1.Text)%> runat=server /><br>

<asp:button text="计算奇偶" id="button1" Onclick="EnterBtn_Click" runat=server/>

     </form>

</body>

</html>

10.3.4 绑定到集合类对象

像DataGrid、ListBox、DrowDownList这样的服务器控件的列表都可以绑定到公共语言运行库的集合类对象,如ArrayList、Hashtable等。下面的示例说明如何将DrowDownList控件的下拉列表绑定到ArrayList类对象。单击按钮,标签将显示所作的选择。

<html>

    <script language="C#" runat="server">

        void Page_Load(Object Sender, EventArgs E)

{   ArrayList values = new ArrayList();

           values.Add ("北京");

           values.Add ("上海");

           DropDown1.DataSource=values;//注意属性DataSource用法

            DropDown1.DataBind();

         }

        void SubmitBtn_Click(Object sender, EventArgs e)

{   Label1.Text="您选择了:"+DropDown1.SelectedItem.Text;

        }

    </script>

<body>

        <h3>DropDownList控件下拉列表绑定到ArrayList类对象</h3>

        <form runat=server>

            <asp:DropDownList id="DropDown1" runat="server"/><BR>

            <asp:button Text="提交" OnClick="SubmitBtn_Click" runat=server/><BR>

            <asp:Label id=Label1 runat="server"/>

        </form>

</body>

</html>

请读者将ArrayList类对象绑定到ListBox控件的列表。绑定到哈希表(Hashtable)的例子见例子e10_5_1。

10.3.5 绑定到数据库表

下面介绍如何将数据库表绑定到ListBox、DrowDownList、RadioButtonList、CheckBoxList的方法。这些控件和绑定数据库表有关的属性有3个:

l DataSource:指定要绑定的数据库表的视图。

l DataTextField:此属性绑定到DataSource指定的数据库表的某字段。这些数据将出现在ListBox和DrowDownList的列表中,或作为RadioButtonList和CheckBoxList的标题。

l DataValueField:此属性绑定到DataSource指定的数据库表的某字段。

下例将学生信息库SdudentI的学生情况表Student中的学生姓名和学号字段绑定到DrowDownList控件的下拉列表中,网页文件如下:

<%@ Import namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>

<html>

<script language="C#" runat="server">    

        void Page_Load(Object sender, EventArgs e)

    {   if (Page.IsPostBack)//此条是必需的,否则总选第1个学生

            return;

string s="Provider=Microsoft.Jet.OLEDB.4.0;";

s+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

string txtCommand="SELECT StudentNum,StudentName FROM Student";

OleDbConnection conn=new OleDbConnection(s);

OleDbDataAdapter da=new OleDbDataAdapter(txtCommand,conn);

DataSet ds = new DataSet();

da.Fill(ds,"Student");

//为DropDownList指定数据源

StateList.DataSource=ds.Tables["Student"].DefaultView;

StateList.DataTextField="StudentName";//指定绑定的字段

StateList.DataValueField="StudentNum";

Page.DataBind();

        }

        void SubmitBtn_Click(Object sender, EventArgs e)

{    Label1.Text="StateList的Text="+StateList.SelectedItem.Text+

":StateList的Value="+StateList.SelectedItem.Value;

        }

    </script>

     <body>

        <h3>数据库表绑定到DrowDownList</h3>

        <form runat=server>
<asp:DropDownList id="StateList" runat="server"/><br>
<asp:button Text="提交" OnClick="SubmitBtn_Click" runat=server/><br>
            <asp:Label id="Label1" runat="server"/>
 
 
    </form> 
</body>
</html>

请读者将学生情况表Student的学生姓名和学号字段绑定到RadioButtonList、CheckBoxList和ListBox控件。请注意控件属性DataSource应赋值为ds.Tables["Student"]。

                                        

图10.3.5

10.4  Repeater控件

Repeater控件是一个简单的模板控件,它没有内置的布局或样式,因此必须在此控件的模板内由网页设计者声明所有的HTML布局、格式设置和样式标记。它可以绑定到数据源,按照模板中设定的可视化界面,显示数据源中的所有数据。Repeater控件没有可视化设计方法,只能用Html标记语言标记。本节介绍Repeater控件的使用方法。

10.4.1 Repeater控件概述

Repeater控件有5个模板,使用Repeater控件至少要定义ItemTemplate模板,其它模板可以根据需要增加。Repeater控件以及5个模板的Html标记格式如下:

<asp:Repeater id=Repeater1 runat="server">

<HeaderTemplate>…</HeaderTemplate>            

<ItemTemplate>…</ItemTemplate>

<AlternatingItemTemplate>…</AlternatingItemTemplate>

<SeparatorTemplate>…</SeparatorTemplate>

<FooterTemplate>…</FooterTemplate>

</asp:Repeater>

其中ItemTemplate和AlternatingItemTemplate模板可以绑定数据源,这两个模板一般称作Repeater控件数据显示模板,其它3个模板不能绑定数据源。5个模板的用途如下:

l  HeaderTemplate:定义头部显示的内容和布局。如果没有定义,则不显示任何内容。

l  ItemTemplate:定义要显示的数据和布局。此数据显示模板为必选,可以绑定数据源。

l  AlternatingItemTemplate:数据显示模板要重复使用显示数据,本属性是重复次数(从零开始)为奇数时的数据显示模板。如无定义使用ItemTemplate。此模板可绑定数据源。

l  SeparatorTemplate:数据显示模板重复使用显示数据,该属性定义两次用数据显示模板显示的数据之间的分隔符。如果未定义,则不呈现分隔符。

l  FooterTemplate:定义底部的显示内容和布局。如果没有定义,则不显示任何内容。

该控件首先按照HeaderTemplate模板显示头部内容。然后按照模板ItemTemplate和AlternatingItemTemplate显示绑定的数据,要重复多次,直到把绑定的数据显示完。模板SeparatorTemplate为两组数据之间增加分隔符。最后按照模板FooterTemplate显示底部内容。

Repeater控件常用属性、事件和方法如下:

l  属性Items:数据显示模板重复使用,建立多个RepeaterItem对象记录按照数据显示模板显示的数据,该只读属性是Repeater控件中RepeaterItem对象的集合。见例e10_4_4。

l  属性DataSource:要绑定的数据源。如数据源是DataSet,必须指定属性DataMember。其它数据源,例如DataTable、DataView、ArrayList等,不必指定属性DataMember,

l  属性DataMember:如数据源是DataSet,该属性为DataSet中的表名。

l  属性Controls:数据显示模板中可以放置控件,RepeaterItem对象记录这些控件,该属性是RepeaterItem对象中子控件的集合。使用方法见例e10_4_4。又见下例:

if (Repeater1.Items.Count>0)//如果Items项数>0

{   Label1.Text="Repeater控件Items第1列包含的所有控件名称如下:<br>";

foreach(RepeaterItem item in Repeater1.Items)

    {   Label1.Text+=((DataBoundLiteralControl)item.Controls[0]).Text+"br";

}

}

l  事件ItemCommand:单击Repeater控件中的按钮时发生。例子见10.4.4节。

l  方法DataBind:该方法使控件及子控件用绑定的数据源更新数据,并用指定格式显示。

例子e10_4_1:下面的示例说明如何将Repeater控件绑定到ArrayList类对象,本例只使用了ItemTemplate模板。网页文件如下:

<html>

    <script language="C#" runat="server">

        void Page_Load(Object sender, EventArgs e)

        {   ArrayList Citys=new ArrayList();

            Citys.Add ("北京");

            Citys.Add ("上海");

            repeater1.DataSource=Citys;//指定数据源

            repeater1.DataBind();//数据绑定,更新数据

         }

    </script>

<body>

        <h3>Repeater控件绑定到ArrayList类对象</h3>

        <form runat=server>

           <asp:Repeater id="repeater1" runat="server">

              <ItemTemplate>

               <%#Container.DataItem%> <BR>

              </ItemTemplate>

            </asp:Repeater>

        </form>

</body>

</html>

运行后显示效果如右图,因为Citys集合中有两个元素,所以显示了两行。

10.4.2 用Repeater控件显示数据库表

例子e10_4_2:下面的示例说明如何将Repeater控件绑定到StudentI数据库的Student表。网页文件如下:

<%@ Import namespace="System.Data" %>

<%@ Import Namespace="System.Data.OleDb" %>

<html>

<script language="C#" runat="server">

    void Page_Load(Object sender, EventArgs e)

{   string s="Provider=Microsoft.Jet.OLEDB.4.0;";

s+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

string txtCommand="SELECT * FROM Student";

OleDbConnection conn=new OleDbConnection(s);

OleDbDataAdapter da=new OleDbDataAdapter(txtCommand,conn);

DataSet ds=new DataSet();

da.Fill(ds,"MyTable");

repeater1.DataSource=ds.Tables["MyTable"].DefaultView;

repeater1.DataBind();

     }

</script>

<body>

    <form runat=server>

      <asp:Repeater id="repeater1" runat="server">

          <HeaderTemplate>

             <table border=1>

                <tr>学生情况表</tr>

<tr>

                  <td> 学 号 </td> <td> 姓 名 </td> <td> 性 别 </td>

                </tr>

</HeaderTemplate>

<ItemTemplate>

            <tr>

<td><%# DataBinder.Eval(Container.DataItem, "StudentNum") %></td>

<td><%# DataBinder.Eval(Container.DataItem, "StudentName")%></td>

<td><%# DataBinder.Eval(Container.DataItem, "StudentSex")%></td>

            </tr>

</ItemTemplate>

          <FooterTemplate> </table> </FooterTemplate>

      </asp:Repeater>

    </form>

</body>

</html>

此网页把学生情况表用表的形式显示出来,显示效果如下图。用Html语言标记一个表采用如下格式:

<table border=1>

<tr><td>第1行第1列</td><td>第1行第2列</td><td>第1行第3列</td></tr>

<tr><td>第2行第1列</td><td>第2行第2列</td><td>第2行第3列</td></tr>

</table>

请注意Repeater控件是如何使用表的Html标记的。Repeater控件是唯一可以把Html标记分开的控件(例如此例Table标记)。一般数据表格为了增加可读性,把两个记录之间用分隔符分开,将下边的标记放到上边网页的适当位置,在两个记录之间用虚线分开。

<SeparatorTemplate>

<tr>

  <td>------------</td>

<td>------------</td>

<td>-----------</td>

</tr>

</SeparatorTemplate>

也可以像定义ItemTemplate模板一样定义AlternatingItemTemplate模板,这样奇数行将按照AlternatingItemTemplate模板定义的模式显示。

10.4.3 DataBinder.Eval方法

上例用到了方法DataBinder.Eval,它有三个参数,第一个参数是数据源的当前记录,在像DataList、DataGrid或Repeater这样的模板控件中,该参数始终是Container.DataItem,第二个参数是数据表字段名,第三个参数为格式字符串,例如"{0:c}"表示货币类型、"{0:N2}"表示整型、"{0:d}"表示时间类型。该方法把数据库表当前记录(参数1指定)中某字段(参数2指定)数据转换为参数3指定数据类型的字符串。参数3是可选的。如果省略它,则 DataBinder.Eval将此字段的数据转换为字段本身的数据类型的字符串。具体的实例如下:

<%@ Import namespace="System.Data" %>

<html>

    <script language="C#" runat="server">

        void Page_Load(Object sender, EventArgs e)

        {   DataTable dt = new DataTable();//创建一个数据库表类对象

            DataRow dr;//本句创建记录类变量,以下4句增加字段

            dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32)));

            dt.Columns.Add(new DataColumn("StringValue", typeof(string)));

            dt.Columns.Add(new DataColumn("DateTimeValue", typeof(DateTime)));

            dt.Columns.Add(new DataColumn("BoolValue", typeof(bool)));

            for (int i=0;i<2;i++)//增加2个记录

            {   dr = dt.NewRow();//创建记录类对象

                dr[0] = i;//为记录的每个字段赋值

                dr[1] = "项" + i.ToString();

                dr[2] = DateTime.Now;

                dr[3] = (i % 2 != 0) ? true : false;

                dt.Rows.Add(dr);//将创建的记录添加到数据库表中

            }

            repeater1.DataSource = new DataView(dt);

            repeater1.DataBind();

         }       

    </script>

<body>

   <h3>DataBinder.Eval方法使用</h3>

   <form runat=server>

      <asp:Repeater id="repeater1" runat="server">

         <ItemTemplate>

时间:<%#DataBinder.Eval(Container.DataItem,

"DateTimeValue","{0:d}")%>

整型值:<%#DataBinder.Eval(Container.DataItem,

"IntegerValue","{0:N2}")%>

          字符串:<%#DataBinder.Eval(Container.DataItem,"StringValue")%>

布尔变量:<asp:CheckBox id=chk1 runat=server Checked=

'<%#(bool)DataBinder.Eval(Container.DataItem,"BoolValue")%>'/><BR>

          </ItemTemplate>

       </asp:Repeater>

    </form>

</body>

</html>

显示效果如右图:请注意,不同类型的不同显示格式。

10.4.4 Repeater控件事件ItemCommand

从上节的例子中可以看出,可以在Repeater控件模板ItemTemplate中放置服务器端控件。如果放置按钮控件,应能响应事件,由于按钮是自动生成的,分别为每一个按钮增加事件处理函数是不可能的。用户单击Repeater控件中的任何按钮,都会产生ItemCommand事件,用ItemCommand事件处理函数的参数2可以判断单击了哪个按钮:产生事件的按钮对象的id 为((Button)e.CommandSource);通过e.CommandName也可以区分不同按钮;Repeater1.Items[e.Item.ItemIndex]可得到与该事件关联的RepeaterItem对象。

例e10_4_4:用Repeater1控件显示学生情况表Student,将Student表的学号列变为按钮列,标题为学生学号,单击此按钮,Repeater2控件显示学号为按钮标题的学生成绩。

<%@ Import namespace="System.Data" %>

<%@ Import Namespace="System.Data.OleDb" %>

<html>

<script language="C#" runat="server">

    DataView dw;

    DataSet ds;

    OleDbConnection conn;

    string s;

    void Repeater1_Bind()//Repeater1数据绑定到Student表视图

    {  s="Provider=Microsoft.Jet.OLEDB.4.0;";

       s+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

       conn=new OleDbConnection(s);

       s="SELECT * FROM Student";

       OleDbDataAdapter da=new OleDbDataAdapter(s,conn);

       ds=new DataSet();

       da.Fill(ds,"Student");

       Repeater1.DataSource=ds.Tables["Student"].DefaultView;

       Repeater1.DataBind();

    }

    void Repeater2_Bind(string s3)//repeater2数据绑定到Score表视图

    {  s="SELECT * FROM Score";

       OleDbDataAdapter da1=new OleDbDataAdapter(s,conn);

       da1.Fill(ds,"Score");

       dw=new DataView(ds.Tables["Score"]);//建立Score表视图

       dw.RowFilter=s3;//参数s3为选择纪录的条件

       repeater2.DataSource=dw;//指定repeater2数据源

       repeater2.DataBind();//数据绑定

    }

    void Page_Load(Object sender, EventArgs e)

    {  if (!Page.IsPostBack)//如果不是事件要求刷新页面,执行函数

       {  Repeater1_Bind();//上条是必需的,否则总选第1个学生

          s="StudentNum="+ds.Tables["Student"].Rows[0]["StudentNum"];

          Repeater2_Bind(s);//初始显示第一个学生的学习成绩

       }

    }

    void r1_Command(Object Sender, RepeaterCommandEventArgs e)

{  if(e.CommandName=="No1Button")//可能有多个按钮列,都产生此事件。

{  Repeater1_Bind();

   s="StudentNum="+((Button)e.CommandSource).Text;

   Repeater2_Bind(s);

   RepeaterItem item=Repeater1.Items[e.Item.ItemIndex];//注意此句及后句用法

   label1.Text=((DataBoundLiteralControl)item.Controls[2]).Text+"学习成绩";

}//如果有其它按钮列,可采用switch语句,不同按钮列,用不同语句处理

    }

</script>

<body>

    <form runat=server>

    <asp:Repeater id=Repeater1 OnItemCommand="r1_Command" runat="server">

         <HeaderTemplate> <table border=1> </HeaderTemplate>

      <ItemTemplate>

         <tr>

          <td><asp:button Text='<%#DataBinder.Eval(Container.DataItem,"StudentNum")%>'

CommandName="No1Button"  runat=server />  </td>

          <td><%# DataBinder.Eval(Container.DataItem,"StudentName")%></td>

          <td><%# DataBinder.Eval(Container.DataItem,"StudentSex")%></td>

        </tr>

      </ItemTemplate>

      <FooterTemplate> </table> </FooterTemplate>

    </asp:Repeater>

    <asp:Label id=label1 runat="server"/>

    <asp:Repeater id="repeater2" runat="server">

         <HeaderTemplate> <table border=1> </HeaderTemplate>

      <ItemTemplate>

         <tr>

          <td><%# DataBinder.Eval(Container.DataItem, "ClassName")%></td>

          <td><%# DataBinder.Eval(Container.DataItem, "Score")%></td>

           </tr>

      </ItemTemplate>

<FooterTemplate> </table> </FooterTemplate>

    </asp:Repeater>

   </form>

</body>

</html>

运行,按钮列的标题为学生学号,单击标题为"2"的按钮,Repeater2控件显示学号为2的学生的成绩。运行效果如右图。Repeater2也可以不用视图作为数据源,直接用Sql语句选择指定学生的学习成绩,这个请读者完成。

10.5  DataList控件

DataList控件也是使用模板来显示被绑定数据源数据的模板控件,它除了具有Repeater控件的大部分功能外,还提供了更多的模板以及各种模板的样式,增加了一些属性,例如控制控件布局属性、与检索有关的属性等,提供了更多的事件,使控件的功能更加强大。该控件支持可视化设计,也为编程提供了便利。

10.5.1 DataList控件概述

DataList控件有7个模板,使用DataList控件至少定义ItemTemplate模板,其它模板可以根据需要增加。用Html标记DataList控件模板的格式和Repeater控件相同,只是多了模板EditItemTemplate和SelectedItemTemplate。2个模板用途如下:

l EditItemTemplate:如果定义了该模板,DataList中当前要编辑的项将按照模板布局显示数据。如果未定义,则使用ItemTemplate模板。可以绑定数据源。

l SelectedItemTemplate:如果定义了该模板,DataList中当前选定项将按照模板布局显示数据。如果未定义,则使用ItemTemplate模板。可以绑定数据源。

DataList控件常用属性和事件、方法如下,这里只介绍和Repeater控件不同部分,相同部分参见Repeater控件。

l 属性RepeatDirection:指定显示方向。Vertical表示垂直显示方向;Horizontal表示水平显示方向。默认值为Vertical。如果有2行3列,下面显示两种显示方向的不同:

1     2     3                                 1     3     5

         4     5     6                                 2     4     6

    水平显示方向                           垂直显示方向

l  属性RepeatColumns:获取或设置要在 DataList 控件中显示的列数。

l  属性ShowFooter和ShowHeader:布尔变量,显示或隐藏页脚或页眉。

l  属性RepeatLayout:为RepeatLayout.Flow将以流布局方式显示DataList。为RepeatLayout.Table将以表的形式显示DataList。

l  属性SelectedIndex:获取或设置 DataList 控件中选定项的索引。若不选定任何项,请将SelectedIndex属性设置为-1。

l  属性SelectedItem :获取 DataList 控件中的选定项。如果ItemTemplate模板中包括一个Label控件,其id值为Label1,用如下语句找到这个控件:

((Label)DataList1.SelectedItem.FindControl("Label1"));

l  模板样式属性AlternatingItemStyle、EditItemStyle、FooterStyle、HeaderStyle、ItemStyle、SelectedItemStyle、SeparatorStyle。控件外观的属性很多,这里不一一列举了,见下例:

<asp:DataList id="grid" runat="server" visible="false" CssClass="Shadow"

BackColor="white" CellPadding="2" CellSpacing="2"

GridLines="none" BorderStyle="solid" BorderColor="black"

BorderWidth="1" font-size="x-small" font-names="verdana">

        <AlternatingItemStyle BackColor="palegoldenrod" />

        <ItemStyle BackColor="beige" />

        <HeaderStyle ForeColor="white" BackColor="brown" Font-Bold="true" />

</asp:DataList>

其中定义了控件DataList的背景为白色,边界为黑实线,宽度为1个象素,字体为"x-small",字体名字为"verdana"。奇数行的背景颜色,数据项的背景色等,页眉中的字的颜色,背景色。。

l  除了支持事件ItemCommand,还支持事件CancelCommand(单击Cancel按钮时发生)、DeleteCommand(单击Delete按钮时发生)、EditCommand(单击Edit按钮时发生)、SelectedIndexChanged (选择了不同的项时发生)。按钮属性CommandName决定产生哪一个事件,例如:CommandName="Cancel",产生CancelCommand事件。这些事件参数的意义和事件ItemCommand参数意义相同。

例子e10_5_1:将e10_4_1网页文件中的Repeater改为DataList,其显示效果不变。下例说明如何将DataList控件绑定到Hashtable类对象,本例只使用了ItemTemplate模板。网页文件如下:

<html>
<script language="C#" runat="server">
        void Page_Load(Object sender, EventArgs e)
        {    if (!Page.IsPostBack)
             {    Hashtable h = new Hashtable();//注意哈希表的使用
                  h.Add ("键 1", "值 1");//哈希表的每一个元素是一对键和值
                  h.Add ("键 2", "值 2");
                  h.Add ("键 3", "值 3");
                  MyDataList.DataSource=h;//为列表框指定数据源
                  MyDataList.DataBind();//数据更新
              }
        }
    </script>
<body>
        <h3>DataList到哈希表的数据绑定</h3>
        <form runat=server>
            <asp:DataList id="MyDataList" runat="server">
<ItemTemplate>
                    <%# ((DictionaryEntry)Container.DataItem).Key %> :
                    <%# ((DictionaryEntry)Container.DataItem).Value %>
</ItemTemplate>
            </asp:DataList>
        </form>
</body>

</html>

10.5.2 使用模板SelectedItemTemplate

例子e10_5_2:该例要求未选中行只显示Student表中的学生姓名和按钮。单击按钮,将显示该按钮所在行学生的详细信息。

网页文件在ItemTemplate模板中绑定Student表中的学生姓名字段,并增加了1列按钮。在DataList控件的Html标记中声明了按钮单击事件处理函数名称:OnItemCommand ="DataList_ItemCommand"。在script标记中定义了事件处理函数DataList_ItemCommand,单击按钮,将自动调用这个事件处理函数,将使当前选定行使用SelectedItemTemplate模板显示数据,即该行学生的详细信息。网页文件如下:

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.OleDb" %>

<html>

<script language="C#" runat="server">

DataSet ds;

      void DataList1_Bind()//DataList1数据绑定到Student表视图

      {  string s="Provider=Microsoft.Jet.OLEDB.4.0;";

         s+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

         OleDbConnection conn=new OleDbConnection(s);

         s="SELECT * FROM Student";

         OleDbDataAdapter da=new OleDbDataAdapter(s,conn);

         ds=new DataSet();

         da.Fill(ds,"Student");

         DataList1.DataSource=ds.Tables["Student"].DefaultView;

         DataList1.DataBind();

      }

      void Page_Load(Object sender, EventArgs e)

{ if (!Page.IsPostBack)

           DataList1_Bind();

      }//以下定义按钮OnItemCommand事件的事件处理函数DataList_ItemCommand

      void DataList_ItemCommand(Object sender, DataListCommandEventArgs e)

      {   DataList1.SelectedIndex=e.Item.ItemIndex;

DataList1_Bind();//选定行使用SelectedItemTemplate模板显示数据

}//如果有多列按钮列,要根据CommandName执行不同程序

  </script>

<body>

    <form runat=server>

      <asp:DataList id="DataList1" runat="server" GridLines="Both" CellPadding="3"

                  CellSpacing="0" OnItemCommand="DataList_ItemCommand">

          <HeaderStyle BackColor="#aaaadd"> </HeaderStyle>

<AlternatingItemStyle BackColor="Gainsboro"></AlternatingItemStyle>

<SelectedItemStyle BackColor="lightgreen"></SelectedItemStyle>

          <HeaderTemplate>学生情况表</HeaderTemplate>

<ItemTemplate> 

姓名:<%# ((DataRowView)Container.DataItem)["StudentName"] %>

<asp:LinkButton id="button1"  Text="详细信息"  

CommandName="select" runat="server"/> 

</ItemTemplate>

<SelectedItemTemplate>

学号:<%# ((DataRowView)Container.DataItem)["StudentNum"] %>

姓名:<%# ((DataRowView)Container.DataItem)["StudentName"] %>

性别:<%# ((DataRowView)Container.DataItem)["StudentSex"] %>

</SelectedItemTemplate>

      </asp:DataList>

    </form>

</body>

</html>

运行,显示效果如右图,图中选中了第1行。其实这样显示的效果并不好。本例可以这样处理,用DataList显示学号和姓名,并增加一个标题为"详细资料"的按钮,单击按钮,在其右侧显示该学生的详细资料,再用一个Repter控件显示该学生的所有课程成绩,请读者自己实现此功能。

10.5.3 使用模板EditItemTemplate

例子e10_5_3:该例用网页把学生情况表用名片的形式显示出来,并增加一个按钮,单击按钮,提供TextBox控件修改姓名,提供DropDownList修改性别,不允许修改学号,并能删除该记录,保存或忽略所作修改。运行效果见下图。

网页文件在ItemTemplate模板中绑定Student表中的所有字段,并增加了一例按钮,按钮的CommandName为"Edit",单击"Edit"按钮,产生OnEditCommand事件,在DataList控件Html标记中声明了该事件处理函数名称:OnEditCommand="Edit_Command"。在script标记中定义了OnEditCommand事件处理函数Edit_Command,单击按钮,将自动调用这个事件处理函数,将使当前选定项使用EditItemTemplate模板显示数据。在EditItemTemplate模板中,StudentNum字段绑定到Label控件的Text属性,因此不能被修改;StudentName字段绑定到TextBox控件的Text属性;StudentSex字段绑定到DropDownList控件的Text属性。同时定义了3个按钮,标题分别为:"保存修改"、"删除记录"、"忽略修改",按钮CommandName属性分别为:"Update"、"Delete"、"Cancel";在DataList控件Html标记中声明了3个按钮的单击事件处理函数名称分别是:Update_Command、Delete_Command、Cancel_Command,在script标记中定义了这些事件处理函数。

编辑完成后,如果单击"保存修改"或"删除记录"按钮,应保存所作修改。可以把所作的修改用SQL语句直接写回源数据库,再一次执行DataList1.DataBind()语句,将显示新数据。这样做的缺点是要频繁和数据库建立连接。另一个办法是保存到Web服务器端DataSet对象中。但是Web服务器完成网页的处理操作并将它传送至浏览器后,随即移除该网页在服务器端的所有信息,包括网页中定义的DataSet对象的引用ds,引用不存在,垃圾收集器将清除DataSet对象。在第11章中将介绍Session对象,当浏览器进入网站访问网站的第一个网页时,Web服务器将自动创建该用户Session对象,在Session对象中可以建立一些变量,这个Session对象和Session对象中的变量只能被这个访问者使用,其它访问者不能使用。当用户在网站的网页之间跳转时,Session对象和存储在Session对象中的变量不会被清除,这些变量始终存在。当浏览器离开本网站或超过一定时间和网站没有联系,Session对象被撤销,同时存储在Session中的变量也不存在了。因此可以把DataSet对象的引用ds存到Session对象中,这样DataSet对象就可以保留了。Session 使用很简单,语句Session["MyDataSet"]=ds将ds保存Session中;语句ds=(DataSet)Session["MyDataSet"]从Session中取出ds;语句if(Session["MyDataSet"]==null)判断Session变量MyDataSet是否存在。本网页使用Session保存DataSet引用变量ds。网页文件如下:

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.OleDb" %>

<html>

  <script language="C#" runat="server">

    DataSet ds;

    void Page_Load(Object sender, EventArgs e)

    {  GetSource();//每次刷新页面都要执行,使ds引用Web服务器端DataSet对象

       if (!IsPostBack)

             BindList();//只有第一次显示网页时执行

    }

    void BindList()

    {  DataList1.DataSource=ds.Tables["Student"].DefaultView;

       DataList1.DataBind();

    }

    void GetSource()//得到数据源

    {  if(Session["MyDataSet"]==null)//判断Session变量MyDataSet是否存在

       {  string s="Provider=Microsoft.Jet.OLEDB.4.0;";//不存在创建DataSet

          s+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

          OleDbConnection conn=new OleDbConnection(s);

          s="SELECT * FROM Student";

          OleDbDataAdapter da=new OleDbDataAdapter(s,conn);

          ds=new DataSet();

          da.Fill(ds,"Student");

          Session["MyDataSet"]=ds;//在Session对象中保存DataSet对象的引用ds

       }//注意MyDataSet和ds为同一对象的引用

       else

          ds=(DataSet)Session["MyDataSet"];//取出DataSet对象的引用

    }//以下是标题为"编辑当前记录"按钮的单击事件处理函数

    void Edit_Command(Object sender, DataListCommandEventArgs e)

    {  DataList1.EditItemIndex=e.Item.ItemIndex;

       BindList();//选定行使用EditItemTemplate模板显示数据

    }//以下是标题为"忽略修改"按钮的单击事件处理函数

    void Cancel_Command(Object sender,DataListCommandEventArgs e)

    {  DataList1.EditItemIndex=-1;//不编辑任何项,索引号为-1

       BindList();//不保存修改,不再使用EditItemTemplate模板显示数据

    }//以下是标题为"删除记录"按钮的单击事件处理函数

    void Delete_Command(Object sender,DataListCommandEventArgs e)

    {  String s=((Label)e.Item.FindControl("StudentNumLabel")).Text;

       s="StudentNum="+s;

       DataRow[] foundRows=ds.Tables["Student"].Select(s);

       foundRows[0].Delete();

       DataList1.EditItemIndex = -1;

       BindList();

    }//以下是标题为"保存修改"按钮的单击事件处理函数

    void Update_Command(Object sender,DataListCommandEventArgs e)

    {  String sNum=((Label)e.Item.FindControl("StudentNumLabel")).Text;

       String sName=((TextBox)e.Item.FindControl("StudentNameTextBox")).Text;

String sSex=((DropDownList)

e.Item.FindControl("StudentSexDownList")).SelectedItem.Text;

       sNum="StudentNum="+sNum;

       DataRow[] foundRows=ds.Tables["Student"].Select(sNum);

       foundRows[0]["StudentName"]=sName;

       foundRows[0]["StudentSex"]=sSex;

       DataList1.EditItemIndex = -1;

       BindList();

    }

  </script>

  <body>

    <form runat=server>

      <asp:DataList id="DataList1" RepeatLayout="Table" RepeatColumns="3"

           RepeatDirection="Horizontal" ShowBorder="True" GridLines="Both"

           CellPadding="3" CellSpacing="0" OnEditCommand="Edit_Command"

           OnUpdateCommand="Update_Command" OnDeleteCommand="Delete_Command"

           OnCancelCommand="Cancel_Command" runat="server">

        <HeaderStyle BackColor="#aaaadd"> </HeaderStyle>

        <AlternatingItemStyle BackColor="Gainsboro"></AlternatingItemStyle>

        <EditItemStyle BackColor="yellow"></EditItemStyle>

        <HeaderTemplate>学生情况表</HeaderTemplate>

        <ItemTemplate>

          学号:<%# DataBinder.Eval(Container.DataItem,"StudentNum") %><BR>

          姓名:<%# DataBinder.Eval(Container.DataItem,"StudentName")%><BR>

          性别:<%# DataBinder.Eval(Container.DataItem,"StudentSex")%><BR>

          <asp:LinkButton id="EditButton"  Text="编辑当前记录" 

                                   CommandName="Edit" runat="server"/>

        </ItemTemplate>

        <EditItemTemplate>

          学号:<asp:Label id="StudentNumLabel" runat="server"

                Text=<%#DataBinder.Eval(Container.DataItem,"StudentNum")%>/>

<BR>

          姓名:<asp:TextBox id="StudentNameTextBox" runat="server"

                Text=<%# DataBinder.Eval(Container.DataItem,"StudentName")%>/>

<BR>

          性别:<asp:DropDownList id="StudentSexDownList" runat="server"

                Text=<%# DataBinder.Eval(Container.DataItem,"StudentSex")%> >

                           <asp:ListItem>男</asp:ListItem>

                           <asp:ListItem>女</asp:ListItem>

                </asp:DropDownList> <BR>

                <asp:LinkButton id="UpdateButton" Text="保存修改" runat="server"

                        CommandName="Update" />

                <asp:LinkButton id="DeleteButton" Text="删除记录" runat="server"

                        CommandName="Delete" />

                <asp:LinkButton id="CancelButton" Text="忽略修改" runat="server"

                        CommandName="Cancel" />

        </EditItemTemplate>

      </asp:DataList>

    </form>

  </body>

</html>

运行,显示效果如右图。

 

10.5.4 使用VS.Net编辑DataList

例e10_5_4用VS.Net实现例子e10_5_3,但把所作的修改用SQL语句直接写回源数据库。具体步骤如下:

(1)   创建Web应用程序项目。

(2)   按照例子e8_12中的步骤(4)到(8)创建oleDbConnection、oleDbDataAdapter和dataSet类对象oleDbConnection1、oleDbDataAdapter1和dataSet11。

(3)   在Web 窗体中添加 DataList控件。在“属性”窗口中,从DataSource 属性的下拉列表选择dataSet11。从DataMember属性的下拉列表选择学生情况表Student。

(4)   在文件WebForm1.aspx.cs中WebForm1类的Page_Load方法中增加语句如下:

void Page_Load(Object sender, EventArgs e)

{  oleDbDataAdapter1.Fill(dataSet11);//每次刷新页面都要执行

   if (!IsPostBack)

       DataList1.DataBind();//只有第一次显示网页时执行

}

(5)   在VS.Net的"设计"视图中,右击DataList控件,在弹出的快捷菜单中,单击"编辑模板"菜单项子菜单中的"项模板"菜单项,在"设计"视图中显示模板编辑器如右图。将光标移到ItemTemplate下的编辑框,键入"学号:",双击工具箱中的Label控件,添加Label控件到ItemTemplate模板中。单击Label属性DataBindings右侧标题为"…"的按钮,出现"Label数据绑定"对话框如图10.5.4A。按图中那样选择,绑定Label控件的Text属性到数据表Student的字段StudentNum。采用同样的步骤用Label控件显示学生姓名和学生性别,并绑定到数据表Student的相应字段。增加LinkButton按钮,Text属性为"编辑当前记录",CommandName属性为"Edit"。在EditItemTemplate模板中,增加Label控件,其Text属性绑定到学生的学号字段,增加TextBox控件,其Text属性绑定到学生的姓名字段,增加DropDownList控件,其下拉列表增加男和女两项,其Text属性绑定到学生性别字段。增加2个LinkButton按钮,Text属性分别为:保存修改、忽略修改。CommandName属性分别为"Update"和"Cancel"。右击模板编辑器,在弹出快捷菜单中,单击"结束模板编辑"菜单项,退出模板编辑状态。

 

                                                   图10.5.4A

(6)   为DataList 控件增加事件EditCommand、UpdateCommand、CancelCommand的事件处理函数如下:

private void DataList1_EditCommand(object source,

System.Web.UI.WebControls.DataListCommandEventArgs e)

{   DataList1.EditItemIndex=e.Item.ItemIndex;

    DataList1.DataBind();

}

private void DataList1_UpdateCommand(object source,

System.Web.UI.WebControls.DataListCommandEventArgs e)

{   String sNum=((Label)e.Item.FindControl("Label7")).Text;

    String sName=((TextBox)e.Item.FindControl("TextBox1")).Text;

    String sSex=

((DropDownList)e.Item.FindControl("DropDownList1")).SelectedItem.Text;

    sNum="StudentNum="+sNum;

    DataRow[] foundRows=dataSet11.Tables["Student"].Select(sNum);

    foundRows[0]["StudentName"]=sName;

    foundRows[0]["StudentSex"]=sSex;

    oleDbDataAdapter1.Update(dataSet11);//保存到源数据库

    DataList1.EditItemIndex=-1;

    DataList1.DataBind();

}

private void DataList1_CancelCommand(object source,

System.Web.UI.WebControls.DataListCommandEventArgs e)

{   DataList1.EditItemIndex=-1;

    DataList1.DataBind();

}

(7)运行,效果和例子e10_5_3基本一致。但本例修改数据后,数据将被直接保存到源数据库中。用VS.Net生成的程序,每次网页重新装载时,自动执行OnInit()程序,将重建oleDbConnection、oleDbDataAdapter和dataSet类对象,网页可以使用这些对象。而DataList1_UpdateCommand()方法中语句oleDbDataAdapter1.Update(dataSet11)将保存修改数据到源数据库。

(8)可以修改DataList 控件的外观属性,修改控件外观。右击 DataList 控件,在弹出快捷菜单中,单击"属性生成器"菜单项,在打开的"DataList属性"对话框中,可以更加方便的修改属性。另外,右击 DataList 控件,打开快捷菜单,单击"自动套用格式"菜单项,在打开的"自动套用格式"对话框中,可以选择已定义好的一些dataList外观样式,这些样式的dataList对象都有比较漂亮的外观。

10.6  DataGraid控件

DataGraid控件是一个数据绑定列表控件,使用DataGrid控件可以显示数据库中的表,将数据库表的字段作为表中的列显示,DataGrid 控件中的每一行表示数据库表的一个记录。DataGrid 控件支持选择、编辑、删除、分页、排序、增加标题行和脚注行等功能。本节介绍该控件的使用方法。本节的例子都是用记事本程序编写的,使用VS.Net的例子见10.9节VS.Net实现留言板。

10.6.1   DataGrid控件概述

该控件属性众多,使用复杂,这里就不全部列出,以后将逐步介绍,包括部分属性的DataGrid控件的html标记格式如下:

<asp:DataGrid id="grid" runat="server" AutoGenerateColumns="true" CssClass="Shadow" BackColor="white" CellPadding="2" CellSpacing="2" GridLines="none" BorderStyle="solid" BorderColor="black" BorderWidth="1" font-size="x-small" ont-names="verdana">
<AlternatingItemStyle BackColor="palegoldenrod" />
<ItemStyle BackColor="beige" />
<HeaderStyle ForeColor="white" BackColor="brown" Font-Bold="true" />

</asp:DataGrid>

这里列出的属性大部分是定义控件的外观的,这里定义控件DataGrid的背景为白色,边界为黑实线,宽度为1个象素,字体为"x-small",字体名字为"verdana"。奇数行的背景颜色,标题的字的颜色,背景色。数据项的背景色等,这里就不一一解释了。使用VS.Net集成环境在Web窗体中放置DataGrid控件后,右击该控件,在弹出菜单中单击"自动套用格式"菜单项,在打开对话框中选用自己喜欢的格式,将自动设定这些属性。

10.6.2   DataGrid控件绑定数据库表

例子e10_6_2:该例把数据库StudentI中的表Student绑定到DataGrid控件,显示学生的信息。在DataGrid控件Html标记中有一些设置外观的属性,请读者把这些有关外观的属性设置和实际显示效果对照,理解这些属性的意义。网页文件如下:

<%@ Import Namespace="System.Data.OleDb" %>

<%@ Import Namespace="System.Data" %>

<html>

<script runat=server Language="C#">

public void Page_Load(Object sender, EventArgs e)

{   string s1="Provider=Microsoft.Jet.OLEDB.4.0;";

s1+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

        string s2="SELECT StudentNum,StudentName,StudentSex FROM student";

        OleDbConnection conn=new OleDbConnection(s1);

        OleDbDataAdapter da=new OleDbDataAdapter(s2,conn); 

        DataSet ds = new DataSet();

        da.Fill(ds,"MyTable");

        grid.DataSource=ds.Tables["MyTable"];

        grid.DataBind();

    }

</script>

<body>

<form runat=server>

<asp:DataGrid id="grid" runat="server" AutoGenerateColumns="true"

          CssClass="Shadow" BackColor="white"   CellPadding="2"

CellSpacing="2" GridLines="none" BorderStyle="solid"

BorderColor="black" BorderWidth="1" font-size="x-small"

font-names="verdana">

          <AlternatingItemStyle BackColor="palegoldenrod" />

          <ItemStyle BackColor="beige" />

          <HeaderStyle ForeColor="white" BackColor="brown" Font-Bold="true"/>

      </asp:DataGrid>

</form>

</body>

</html>

Page_Load()函数说明了显示数据的必要步骤。特别注意DataGrid控件数据绑定的方法。显示效果如右图。

10.6.3   DataGrid控件对数据库记录分页显示

如果要显示的数据库表的记录很多,无法一页显示,可采用分页的办法。DataGrid控件和分页有关的属性和事件如下:

l  属性AllowPaging:为True表示允许分页,为false表示不允许分页。如果允许分页,则在DataGrid控件底部出现分页导航栏,导航栏有若干按钮,单击按钮显示指定页。

l  属性PageSize:表示每页显示的记录数。

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

l  属性PageCount:根据属性PageSize设定的每页记录数,计算的总页数。只读属性。

l  属性PagerStyle:该属性设置分页导航栏风格。PagerStyle.Mode表示导航栏的模式,如PagerStyle.Mode=NumericPages,则导航栏按钮标题为页号,外观如下图,单击按钮,将显示按钮标题指定的页。PagerStyle.PageButtonCount为分页导航栏按钮的个数。如果PagerStyle.Mode=NextPrev,则导航栏按钮标题为"<"和">",分别单击标题为"<"或">"的按钮,则显示前页或后页。也可修改按钮标题为字符,例如修改为"前页"和"后页",可修改属性PagerStyle.PrevPageText="前页",PagerStyle.NextPageText="后页"。

l  事件OnPageIndexChanged:单击分页导航栏中的按钮,要求DataGrid控件显示新页时产生的事件。事件处理函数修改当前显示页的索引号为新页的索引号(e.NewPageIndex)。

例子e10_6_3:把数据库StudentI的表Student绑定到DataGrid控件,分页显示,每页3个记录。网页文件如下:

<%@ Import Namespace="System.Data"%>

<%@ Import Namespace="System.Data.OleDb"%>

<html>

<script runat="server" Language="C#">

    DataSet ds;

public void Page_Load(Object sender, EventArgs e)

{   string s1="Provider=Microsoft.Jet.OLEDB.4.0;";

            s1+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

            string s2="SELECT StudentNum,StudentName,StudentSex FROM student";

            OleDbConnection conn=new OleDbConnection(s1);

            OleDbDataAdapter da=new OleDbDataAdapter(s2,conn); 

            ds=new DataSet();

            da.Fill(ds,"MyTable");

            grid.DataSource=ds.Tables["MyTable"];

            grid.DataBind();//注意方法Page_Load中无语句if (!Page.IsPostBack)

}//因此每次刷新页面该方法被执行,ds对象被重建,方法IndexChanged可用ds

public void IndexChanged(Object sender,DataGridPageChangedEventArgs e)

{   grid.CurrentPageIndex=e.NewPageIndex;//改变当前显示页的索引号

            grid.DataSource=ds.Tables["MyTable"];

            grid.DataBind();//注意ds对象在方法Page_Load中被重建,可直接使用

}//否则必须自己建立ds对象

</script>

<body>

<form runat="server">

<asp:DataGrid id="grid" runat="server" GridLines="both" PageSize="3"

AllowPaging="True" OnPageIndexChanged="IndexChanged" >

            <PagerStyle PageButtonCount="3" Font-Bold="true" Mode="NumericPages"

BackColor="palegreen" />

          </asp:datagrid>

</form>

</body>

</html>

显示效果如上图,这里分页导航栏使用标题为页编号的按钮,请读者修改为使用标题为"前页"和"后页"的按钮。为了使程序更加清楚,对DataGrid控件Html标记中有关外观的属性设置作了简化,界面不如上例漂亮。以后的例题都是用这个简单的DataGrid控件标记。

10.6.4   DataGrid控件列模板类型

前两节例子,用DataGrid控件显示数据库StudentI中的Student表,将Student表的字段作为表中的列,列标题为字段名。DataGrid 控件中的每一行表示数据库表的一个记录,所有这些工作都是自动完成的。为了避免不兼容,字段名一般用英文,但显示时要将DataGrid列标题改为中文。有时还希望改变字段的显示顺序。为了实现这些功能,就不能自动创建DataGrid列,而要在DataGrid控件Html标记中自己增加Html标记创建列,为此必须置AutoGenerateColumns=false。DataGrid控件支持5种列模板类型,这些列模板是:

l  BoundColumn:创建1列显示被绑定数据表的1个字段的数据,数据以纯文本显示。

l  ButtonColumn: 创建1列按钮,按钮标题可以是增加记录、删除等,按钮标题也可以绑定到数据源的指定字段。

l  EditCommandColumn: 创建1列按钮,单击按钮,执行编辑按钮所在行的命令。

l  HyperLinkColumn: 创建1列超级链接,超级链接字符可以是固定字符,也可以绑定到数据源的指定字段。单击超级链接字符,可以超级链接到其它网页。

l  TemplateColumn: 按照指定的模板创建列,可以在列中增加Web服务器端控件。

所有这些列的Html标记要放到DataGrid的子标记<columns></columns>之间,以后各节将详细介绍这些列类型的使用方法。

10.6.5   用BoundColumn列将标题改为中文

如果DataGrid控件属性AutoGenerateColumns=true,DataGrid控件将根据数据库表的内容自动填充表格,列标题是字段名。由于避免不兼容,字段名一般用英文,如希望显示时要将DataGrid列标题改为中文,可以置AutoGenerateColumns=false,在DataGrid控件Html标记中,用Html标记BoundColumn列模板创建列。BoundColumn列模板类常用属性如下:

l  DataField:该列要绑定的数据表字段名称。

l  HeaderText:列标题(页眉)字符串,可以改为中文。

l  DataFormatString:定义该列数据显示格式。数据格式字符串用冒号分隔为两部分,格式为{0:Bxx}。其中的B可以是以下各值:C、D、E、F、G、N、X,分别表示:以货币格式、以十进制格式、以科学记数法(指数)格式、以定点小数格式、以常规格式、以整数格式、以十六进制格式显示数据。格式中的xx指定显示数据的有效位数或小数位数。例如,格式化字符串{0:F2}将显示带两位小数的定点数。

l  ReadOnly:如不允许编辑BoundColumn列的数据,为true;否则为false。默认值为false。

l  SortExpression:列进行排序时所用的排序表达式。

l  属性FooterStyle、FooterText、HeaderImageUrl、HeaderStyle、ItemStyle请用帮助查看。

用Html标记BoundColumn列模板创建列的格式如下:

<columns>

<asp:BoundColumn runat="server" DataField="绑定的字段名" HeaderText="列标题名">

    <itemstyle backcolor="lightblue" font-bold="true" />

</asp:BoundColumn>

</columns>

其中属性HeaderText是列标题字符串,可以改为中文,属性DataField是该列绑定的字段名。<itemstyle…/>是本列的外观属性。希望显示多少列,就要使用多少次列模板控件BoundColumn创建DataGrid列。

例子e10_6_5:把数据库StudentI的表Student绑定到DataGrid控件,显示学生信息,列标题改为中文。网页文件如下:

<%@ Import Namespace="System.Data.OleDb" %>

<%@ Import Namespace="System.Data" %>

<html>

<script runat=server Language="C#">

public void Page_Load(Object sender, EventArgs e)

{   string s1="Provider=Microsoft.Jet.OLEDB.4.0;";

s1+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

        string s2="SELECT StudentNum,StudentName,StudentSex FROM student";

        OleDbConnection conn=new OleDbConnection(s1);

        OleDbDataAdapter da=new OleDbDataAdapter(s2,conn); 

        DataSet ds = new DataSet();

        da.Fill(ds,"MyTable");

        grid.DataSource=ds.Tables["MyTable"];

        grid.DataBind();

    }

</script>

<body>

<form runat=server>

<asp:DataGrid id="grid" runat="server"

GridLines="both" AutoGenerateColumns="false">

        <columns>

          <asp:BoundColumn runat="server"

DataField="StudentNum" HeaderText="编号">

            <itemstyle backcolor="lightblue" font-bold="true" />

         </asp:BoundColumn>

          <asp:BoundColumn runat="server"

DataField="StudentName" HeaderText="姓名" />

          <asp:BoundColumn runat="server"

DataField="StudentSex" HeaderText="性别" />

        </columns>

      </asp:DataGrid>

</form>

</body>

</html>

10.6.6   按钮列模板ButtonColumn

如不自动生成DataGrid列,除了可用列模板BoundColumn创建列,还可使用列模板ButtonColumn增加按钮列,为按钮增加事件处理函数,完成一定功能,例如删除按钮所在行的记录,在按钮所在行前(或后)插入新纪录等。列模板类ButtonColumn一些属性和列模板类BoundColumn相同,这里只介绍和列模板类BoundColumn不同的常用属性:

l  ButtonType:按钮的类型,可以是LinkButton(默认值)或PushButton。

l  Text:按钮中显示的标题。如果设置了Text属性,则该列中的所有按钮均共享该标题。

l  CommandName:字符串类型。可以创建多列按钮,但所有列按钮都产生ItemCommand 事件,在该事件处理函数中,要根据CommandName确定用户单击了哪列按钮。

例子e10_6_6:用一个DataGrid控件显示学生的信息,并增加一列按钮列,单击按钮,在另一DataGrid控件中显示按钮所在行的学生的学习成绩。网页文件如下,运行效果如右图。

<%@ Import Namespace="System.Data.OleDb"%>

<%@ Import Namespace="System.Data" %>

<html>

<script runat=server Language="C#">

  DataView dw;

  DataSet ds;

public void Page_Load(Object sender, EventArgs e)

{   string s1="Provider=Microsoft.Jet.OLEDB.4.0;";

        s1+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

        string s2="SELECT StudentNum,StudentName,StudentSex FROM student";

        OleDbConnection conn=new OleDbConnection(s1);

        OleDbDataAdapter da=new OleDbDataAdapter(s2,conn); 

        ds=new DataSet();

        da.Fill(ds,"MyTable");

        grid.DataSource=ds.Tables["MyTable"];

        grid.DataBind();

s2="SELECT * FROM Score";

OleDbDataAdapter da1=new OleDbDataAdapter(s2,conn);

da1.Fill(ds,"Score");

dw=new DataView(ds.Tables["Score"]);

s2="StudentNum="+grid.Items[0].Cells[0].Text;

dw.RowFilter=s2;

grid1.DataSource=dw;//初始显示第一个学生成绩

grid1.DataBind();

    }

public void HandleCommands(Object sender, DataGridCommandEventArgs e)

{   if(e.CommandName=="moreinfo")//判断是哪一列按钮发的事件

        {   string s="StudentNum="+e.Item.Cells[0].Text;

        dw.RowFilter=s;

        grid1.DataSource=dw;//显示指定列的学生成绩

        grid1.DataBind();

        }

}

</script>

<body>

<form runat=server>

<asp:DataGrid id="grid" runat="server" GridLines="both"

OnItemCommand="HandleCommands" AutoGenerateColumns="false">

           <columns>

                <asp:BoundColumn runat="server"

DataField="StudentNum" HeaderText="编号" />

                <asp:BoundColumn runat="server"

DataField="StudentName" HeaderText="姓名" />

                <asp:BoundColumn runat="server"

DataField="StudentSex" HeaderText="性别" />

                <asp:ButtonColumn runat="server"

Text="学习成绩" CommandName="moreinfo" />

            </columns>

        </asp:DataGrid><br>

<asp:DataGrid id="grid1" runat="server" GridLines="both" />

</form>

</body>

</html>

运行效果如上图,图中第2个DataGrid控件中是显示的学号为2的学生的学习成绩。按钮标题也可以绑定到数据源的指定字段。

10.6.7   增加HyperLinkColumn列

控件HyperLinkColumn用来创建超级链接列,超级链接列的字符可以是固定字符,也可以绑定到数据源的指定字段。单击超级链接,可以超级链接到其它网页。

例子e10_6_7A:用一个DataGrid控件显示学生的信息,并增加1列超级链接列,单击超级链接,在另一网页中显示超级链接所在行学生的学习成绩。网页文件如下:

<%@ Import Namespace="System.Data.OleDb" %>

<%@ Import Namespace="System.Data" %>

<html>

<script runat=server Language="C#">

 public void Page_Load(Object sender, EventArgs e)

{   string s1="Provider=Microsoft.Jet.OLEDB.4.0;";

        s1+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

        string s2="SELECT StudentNum,StudentName,StudentSex FROM student";

        OleDbConnection conn=new OleDbConnection(s1);

        OleDbDataAdapter da=new OleDbDataAdapter(s2,conn); 

        DataSet ds=new DataSet();

        da.Fill(ds,"MyTable");

        grid.DataSource=ds.Tables["MyTable"];

        grid.DataBind();

    }

</script>

<body>

<form runat=server>

<asp:DataGrid id="grid" runat="server" GridLines="both"

AutoGenerateColumns="false">

         <columns>

           <asp:BoundColumn runat="server"

DataField="StudentNum" HeaderText="编号" />

            <asp:BoundColumn runat="server"

DataField="StudentName" HeaderText="姓名" />

            <asp:BoundColumn runat="server"

DataField="StudentSex" HeaderText="性别" />

<asp:HyperLinkColumn runat="server" HeaderText="在另一网页显示成绩" 
                  DataNavigateUrlField="StudentNum" DataTextField="StudentName"
                  DataNavigateUrlFormatString="e10_6_7B.aspx?id={0}"                   
                  DataTextFormatString="{0}同学成绩" Target="frInfo"> 
              <ItemStyle BackColor="lightblue" font-bold="true" /> 

            </asp:HyperLinkColumn>

         </columns>

        </asp:DataGrid><br>

</form>

</body>

</html>

在HyperLinkColumn列中,DataNavigateUrlFormatString="e10_6_7B.aspx? id={0}"是超级链接的网页,本例是e10_6_7B.aspx,?id={0}是传递的参数,{0}是变量,对应属性DataNavigateUrlField指定的数据库表字段,本例为SdudentNum;DataTextFormatString是超级链接字符串,本例为"{0}同学成绩",{0}对应DataTextField指定的数据库表字段。

例e10_6_7B:网页显示在网页e10_6_7A中指定学号的同学的学习成绩,网页文件如下:

<%@ Import Namespace="System.Data.OleDb" %>

<%@ Import Namespace="System.Data" %>

<html>

<script runat=server Language="C#">

 public void Page_Load(Object sender, EventArgs e)

{   string s="Provider=Microsoft.Jet.OLEDB.4.0;";

        s+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

        OleDbConnection conn=new OleDbConnection(s);

        s="SELECT * FROM Score";

OleDbDataAdapter da=new OleDbDataAdapter(s,conn);

DataSet ds=new DataSet();

da.Fill(ds,"Score");

DataView dw=new DataView(ds.Tables["Score"]);

s="StudentNum="+Request["id"];//Request用法见第11章

dw.RowFilter=s;

grid1.DataSource=dw;

grid1.DataBind();

    }

</script>

<body>

<form runat=server>

<asp:DataGrid id="grid1" runat="server" GridLines="both" />

</form>

</body>

</html>

 

 

 

 

 

 

 

 

显示效果如上图。右边网页显示的是学号为3的学生的学习成绩。

10.6.8       TemplateColumn列模板的用法

使用列模板TemplateColumn的目的是在DataGrid控件的网格中增加Web服务器控件。使用TemplateColumn列模板创建DataGrid控件列的Html标记格式如下:

<asp:TemplateColumn runat="server" HeaderText="本列标题">

<itemtemplate>

    在此增加服务器控件,用来在非编辑状态下显示数据

</itemtemplate>

<edititemtemplate>

在此增加服务器控件,用来在编辑状态下显示数据

</edititemtemplate>

</asp:TemplateColumn>

    其中,itemtemplate标记是必须的。可以没有edititemtemplate标记,此时在编辑状态下采用TextBox控件修改数据。本节的两个例子都没有使用edititemtemplate标记。使用edititemtemplate标记的例子见下一节。

例子e10_6_8A:该例用列模板TemplateColumn把学生性别列用单选按钮显示。

<%@ Import Namespace="System.Data.OleDb" %>

<%@ Import Namespace="System.Data" %>

<html>

<script runat=server Language="C#">

public void Page_Load(Object sender, EventArgs e)

{   string s1="Provider=Microsoft.Jet.OLEDB.4.0;";

s1+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

        string s2="SELECT StudentNum,StudentName,StudentSex FROM student";

        OleDbConnection conn=new OleDbConnection(s1);

        OleDbDataAdapter da=new OleDbDataAdapter(s2,conn); 

        DataSet ds = new DataSet();

        da.Fill(ds,"MyTable");

        grid.DataSource=ds.Tables["MyTable"];

        grid.DataBind();

    }

    bool GetSex(string sSex)
{  if (sSex!="女")
return true;
return false;
}

</script>

<body>

<form runat=server>

<asp:DataGrid id="grid" runat="server"

GridLines="both" AutoGenerateColumns="false">

        <columns>

          <asp:BoundColumn runat="server" HeaderText="编号"

DataField="StudentNum" />

          <asp:BoundColumn runat="server" HeaderText="姓名"

DataField="StudentName" />

                <asp:TemplateColumn runat="server" HeaderText="男">

<itemtemplate>
               <asp:checkbox runat="server" enabled="false" checked=
                     '<%# GetSex((string)DataBinder.Eval(
                          Container.DataItem,"StudentSex")) %>'/>
</itemtemplate>

          </asp:TemplateColumn>

        </columns>

</asp:DataGrid>

</form>

</body>

</html>

例子e10_6_8B该例用列模板TemplateColumn把学生性别列用图形显示。

<%@ Import Namespace="System.Data.OleDb" %>

<%@ Import Namespace="System.Data" %>

<html>

<script runat=server Language="C#">

public void Page_Load(Object sender, EventArgs e)

{   string s1="Provider=Microsoft.Jet.OLEDB.4.0;";

s1+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

        string s2="SELECT StudentNum,StudentName,StudentSex FROM student";

        OleDbConnection conn=new OleDbConnection(s1);

        OleDbDataAdapter da=new OleDbDataAdapter(s2,conn); 

        DataSet ds = new DataSet();

        da.Fill(ds,"MyTable");

        grid.DataSource=ds.Tables["MyTable"];

        grid.DataBind();

    }

    String GetGifFile(string sex)
     { if (sex!="女")
           return "checked.gif"; 
       return "unchecked.gif";
}//2个.gif文件和e10_6_8B.aspx在同一目录中

</script>

<body>

<form runat=server>

<asp:DataGrid id="grid" runat="server"

GridLines="both"

AutoGenerateColumns="false">

           <columns>

                <asp:BoundColumn runat="server" HeaderText="编号"

DataField="StudentNum" />

                <asp:BoundColumn runat="server" HeaderText="姓名"

DataField="StudentName" />

                      <asp:TemplateColumn runat="server" HeaderText="男">

<itemtemplate>
                       <asp:image runat="server" imageurl='<%#GetGifFile
            ((string)DataBinder.Eval(Container.DataItem,
                                    "StudentSex"))%>'/>
                   </itemtemplate>

                </asp:TemplateColumn>

            </columns>

        </asp:DataGrid>

</form>

</body>

</html>

10.6.9       EditCommandColumn列模板

列模板EditCommandColumn可以在DataGrid控件中增加1列按钮,单击按钮可以进入编辑状态。在编辑状态下,如果用列模板TemplateColumn创建的列中,指定了在编辑状态下完成编辑所用的服务器控件,则用该控件修改数据,否则使用TextBox控件修改数据。使用列模板EditCommandColumn在DataGrid控件中增加1列按钮的Html标记格式如下:

<asp:EditCommandColumn runat="server"

CancelText="忽略" EditText="编辑" UpdateText="确定">

     <itemstyle BackColor="yellow" />

</asp:EditCommandColumn>

这里定义了3个按钮,在非编辑状态下,该列显示标题为"编辑"的按钮,单击此按钮,产生OnEditCommand事件,该事件的事件处理函数将使按钮所在的行进入编辑状态,并将该行的标题为"编辑"的按钮替换为标题为"确定"和"忽略"两个按钮,单击两个按钮分别产生事件OnUpdateCommand和OnCancelCommand,这两个事件的事件处函数分别执行保存修改、忽略修改的操作,并返回非编辑状态。在DataGrid控件Html标记中,指定了3个按钮的单击事件和其相联系的事件处理函数,例如OnEditCommand="Edit_Command"指定标题为"编辑"的按钮的OnEditCommand事件的事件处理函数是Edit_Command。

例子e10_6_9:该例网页把学生情况表Student用DataGrid控件显示出来,Student表每个字段是DataGrid的一列,并增加一个按钮,单击按钮,提供TextBox控件修改姓名,提供DropDownList修改性别,不允许修改学号,能保存或忽略所作修改。

学生情况表共有3个字段,不允许自动生成每个字段的列。其中字段"StudentNum"和"StudentName"用BoundColumn列模板显示;而字段"StudentSex"用TemplateColumn列模板显示,在非编辑状态下用Label控件显示学生性别,在编辑状态下用DropDownList显示学生性别。网页文件如下:

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.OleDb" %>

<html>

  <script language="C#" runat="server">

    DataSet ds;

    void Page_Load(Object sender, EventArgs e)

    {  GetSource();//每次刷新页面都要执行

       if (!IsPostBack)//如果网页响应事件后刷新,不执行其后语句

             BindList();

    }

    void BindList()

    {  Grid.DataSource=ds.Tables["Student"].DefaultView;

       Grid.DataBind();

    }

    void GetSource()//得到数据源

    {  if(Session["MyDataSet"]==null)

       {  string s="Provider=Microsoft.Jet.OLEDB.4.0;";

          s+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

          OleDbConnection conn=new OleDbConnection(s);

          s="SELECT * FROM Student";

          OleDbDataAdapter da=new OleDbDataAdapter(s,conn);

          ds=new DataSet();

          da.Fill(ds,"Student");

          Session["MyDataSet"]=ds;//Session详细介绍见10.5.3节及第11章

       }//注意MyDataSet和ds为同一对象的引用

       else

          ds=(DataSet)Session["MyDataSet"];

    }//以下为标题为"编辑"的按钮单击事件OnEditCommand事件处理函数

    void Edit_Command(Object sender, DataGridCommandEventArgs e)

    {  Grid.EditItemIndex=e.Item.ItemIndex;

       BindList();

    }//以下为标题为"忽略"的按钮单击事件OnCancelCommand事件处理函数

    void Cancel_Command(Object sender, DataGridCommandEventArgs e)

    {  Grid.EditItemIndex = -1;

       BindList();

    }//以下为标题为"确定"的按钮单击事件OnUpdateCommand事件处理函数

    void Update_Command(Object sender, DataGridCommandEventArgs e)

    {  String sName=((TextBox)e.Item.Cells[1].Controls[0]).Text;

       String sSex=((DropDownList)

               e.Item.FindControl("dropDownList1")).SelectedItem.Text;

       string sNum="StudentNum="+Grid.DataKeys[e.Item.ItemIndex];

       DataRow[] foundRows=ds.Tables["Student"].Select(sNum);

       foundRows[0]["StudentName"]=sName;

       foundRows[0]["StudentSex"]=sSex;

       Grid.EditItemIndex = -1;

       BindList();

    }

  </script>

  <body>

    <form runat=server>

<asp:DataGrid id="Grid" runat="server" GridLines="both"

DataKeyField="StudentNum"  AutoGenerateColumns="false"

OnEditCommand="Edit_Command" OnUpdateCommand="Update_Command"

OnCancelCommand="Cancel_Command">

        <columns>

          <asp:BoundColumn runat="server" HeaderText="编号" Readonly="true"

                                 DataField="StudentNum" />

          <asp:BoundColumn runat="server" HeaderText="姓名"

                                 DataField="StudentName" />

          <asp:TemplateColumn runat="server" HeaderText="性别">

            <itemtemplate>

              <asp:Label runat="server"

Text='<%# DataBinder.Eval(Container.DataItem,"StudentSex")%>'/>

            </itemtemplate>

            <edititemtemplate>

              <asp:DropDownList id="dropDownList1" runat="server" >

                <asp:ListItem>男</asp:ListItem>

                <asp:ListItem>女</asp:ListItem>

              </asp:DropDownList>

            </edititemtemplate>

          </asp:TemplateColumn>

          <asp:EditCommandColumn runat="server" CancelText="忽略"

               EditText="编辑" UpdateText="确定">

               <itemstyle BackColor="yellow" />

          </asp:EditCommandColumn>

        </columns>

      </asp:DataGrid>

    </form>

  </body>

</html>

运行效果如右图,图中已单击了第2行的"编辑"按钮,第2行进入了编辑状态,因此第2行出现了进行编辑的控件,右侧按钮也变为标题为"确定"和"忽略"的按钮。请注意,由于编号列为只读,因此没有显示编辑控件;姓名列没有指定编辑控件,因此使用默认的编辑控件TextBox编辑;性别列用列模板TemplateColumn创建的列显示,该模板列中指定了编辑控件为DropDownList,则用该控件修改性别。

10.6.10     DataGrid控件的排序

使用过Excel程序的读者都知道,如果希望对某一列排序,只要双击列标题即可。DataGrid控件也提供了类似的功能。要想启用DataGrid控件的排序功能,必须修改其属性AllowSorting为true(默认值为false),表示允许排序,允许排序的列标题有一下划线,单击允许排序的列标题将产生OnSortCommand事件,事件处理函数名在网页DataGrid控件Html标记中用OnSortCommand="事件处理函数名"声明。网页script标记中应定义排序事件OnSortCommand的事件处理函数。如果自动产生数据库表字段的DataGrid列,则每一列都可以排序,列标题有下划线,单击列标题,将执行OnSortCommand事件处理函数,对该列进行排序。排序的有关设置见下例中背景色为黑色的语句。运行效果见右图。

例子e10_6_10A:自动生成Student表字段DataGrid列的排序例子,网页文件如下:

<%@ Import Namespace="System.Data.OleDb"%>

<%@ Import Namespace="System.Data" %>

<html>

  <script runat=server Language="C#">

    DataView Source;

    public void Page_Load(Object sender, EventArgs e)

    {  string s1="Provider=Microsoft.Jet.OLEDB.4.0;";

       s1+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

       string s2="SELECT StudentNum,StudentName,StudentSex FROM student";

       OleDbConnection conn=new OleDbConnection(s1);

       OleDbDataAdapter da=new OleDbDataAdapter(s2,conn);  

       DataSet ds = new DataSet();

       da.Fill(ds,"MyTable");

       Source=ds.Tables["MyTable"].DefaultView;

       grid.DataSource=Source;

       if(!IsPostBack)

       {  Source.Sort="StudentNum";//初始对字段StudentNum排序

          grid.DataBind();

       }

    }

    void grid_Sort(Object sender, DataGridSortCommandEventArgs e)

    {  Source.Sort=e.SortExpression;//对单击列排序

       grid.DataBind();

    }

  </script>

  <body>

    <form runat=server>

      <asp:DataGrid id="grid" runat="server" GridLines="both"

           OnSortCommand="grid_Sort" AllowSorting="true" />

    </form>

  </body>

</html>

    DataView类的属性Sort为排序表达式,例如要对DataView类对象Source的姓名字段 StudentNum排序,则应采用如下语句Source.Sort="StudentNum",数据绑定后,将对StudentNum字段排序。默认为升序排序,如希望降序排序可以采用如下格式:Source.Sort="StudentNum  DESC"。也可以对多个字段排序,例如希望首先按StudentNum字段排序,再按StudentName字段排序可以采用如下格式:Source.Sort="StudentNum DESC, StudentName"。如果不自动生成DataGrid控件列,必须为DataGrid每一列的属性SortExpression 设定排序表达式,一般为字段名,见下例中背景色为黑色的语句。

例子e10_6_10B不自动生成控件DataGrid列的排序例子如下,运行效果入右图。

<%@ Import Namespace="System.Data.OleDb" %>

<%@ Import Namespace="System.Data" %>

<html>

  <script runat=server Language="C#">

    DataView Source;

    public void Page_Load(Object sender, EventArgs e)

    {  string s1="Provider=Microsoft.Jet.OLEDB.4.0;";

       s1+="Data Source=D:\\ASP\\StudentI.mdb";//Data Source两词之间有空格

       string s2="SELECT StudentNum,StudentName,StudentSex FROM student";

       OleDbConnection conn=new OleDbConnection(s1);

       OleDbDataAdapter da=new OleDbDataAdapter(s2,conn);  

       DataSet ds = new DataSet();

       da.Fill(ds,"MyTable");

       Source=ds.Tables["MyTable"].DefaultView;

       grid.DataSource=Source;

       if(!IsPostBack)

       {  Source.Sort="StudentNum";//初始对字段StudentNum排序

          grid.DataBind();

       }

    }

    void grid_Sort(Object sender, DataGridSortCommandEventArgs e)

    {  Source.Sort=e.SortExpression;

       grid.DataBind();

    }

  </script>

<body>

<form runat=server>

<asp:DataGrid id="grid" runat="server" GridLines="both" AllowSorting="true"

OnSortCommand="grid_Sort" AutoGenerateColumns="false">

           <columns>

                <asp:BoundColumn SortExpression="StudentNum"

DataField="StudentNum" HeaderText="编号" runat="server" />

                <asp:BoundColumn runat="server" SortExpression="StudentName"

DataField="StudentName" HeaderText="姓名" />

                <asp:BoundColumn runat="server" DataField="StudentSex"

HeaderText="性别" />

            </columns>

        </asp:DataGrid>

</form>

</body>

</html>

在DataGrid的3列中,只有标题为"编号"和"姓名"的列为属性SortExpression指定了排序表达式,因此,只有这两列可以排序,表达式SortExpression="StudentNum"表示此列按照学生编号字段"StudentNum"从小到大顺序排序。

10.6.11     使用微软SQL Server数据库系统

例子e10_6_11:把微软数据库Northwind中的表Employees绑定到DataGrid控件,显示所选定字段的数据。注意,要运行此网页,Web服务器所在的计算机,必须安装微软SQL Server7.0或以后版本数据库系统以及其自带的数据库例子Northwind。网页文件如下:

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.SqlClient" %>

<html>

<script runat=server Language="C#">

public void Page_Load(Object sender, EventArgs e)

{   string s1="DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;";

        string s2="SELECT employeeid, firstname, lastname FROM Employees";

        SqlConnection conn=new SqlConnection(s1);

        SqlDataAdapter da=new SqlDataAdapter(s2,conn);

        DataSet ds=new DataSet();

        da.Fill(ds,"EmployeesList ");

        grid.DataSource=ds.Tables["EmployeesList"];//为网格控件指定数据源

        grid.DataBind();//数据绑定

}

</script>

<body>

<form runat=server>

    <asp:DataGrid id="grid" runat="server" AutoGenerateColumns="true"

      CssClass="Shadow" BackColor="white" CellPadding="2" CellSpacing="2"

GridLines="none" BorderStyle="solid" BorderColor="black"

BorderWidth="1" font-size="x-small" font-names="verdana">

      <AlternatingItemStyle BackColor="palegoldenrod" />

      <ItemStyle BackColor="beige" />

      <HeaderStyle ForeColor="white" BackColor="brown" Font-Bold="true"/>

    </asp:DataGrid>

</form>

</body>

</html>

请把本网页背景色为黑色的语句和例子e10_6_2网页相应语句比较,看有什么不同。请读者把本节所有例子改为使用微软SQL Server自带数据库Northwind中的表Employees。

10.7  AdRotator控件

AdRotator控件用于随机并自动循环显示一组广告图片,每刷新一次页面,改变一次显示广告图片。可以控制广告图片的优先级,从而使某些广告图片的显示频率高于其他广告图片。单击AdRotator控件的广告图片,将超级链接到指定网页。控件常用属性意义如下:

l  AdvertisementFile:AdRotator控件用一个XML文件指定每个广告图片的URL,以及单击广告图片超级链接的网页URL等信息。该属性记录XML文件的位置。

l  KeywordFilter:用于筛选出XML文件中相应关键字的图片广告。

l  Target:单击AdRotator控件的广告图片,将超级链接到指定网页,该属性指定这个网页如何打开,为_blank 将在新窗口中打开;_parent 将在父窗口中打开;_self 将在具有焦点的窗口中打开;_search在搜索窗口打开。

例子e10_7:本例使用AdRotator控件显示2个广告图片,使用VS.Net创建步骤如下:

(1) 创建新Web应用程序项目。新建一个XML文件。单击VS.Net菜单"项目"|"添加新项"菜单项,弹出标题为"添加新项"的对话框,在对话框中选中"XML文件",文件名为"ads.xml",单击"打开"按钮,增加一个XML文件。文件如下:

<Advertisements>

 <Ad>

        <ImageUrl>p2.JPG</ImageUrl>

        <NavigateUrl>http://www.sohu.com</NavigateUrl>

        <AlternateText>图像不可用时显示的文本</AlternateText>

        <Impressions>10</Impressions>

        <Keyword>Topic1</Keyword>

        <Caption>第1个图的标题</Caption>

    </Ad>

    <Ad>

        <ImageUrl>p1.jpg</ImageUrl>

        <NavigateUrl>http://www.sina.com</NavigateUrl>

        <AlternateText>图像不可用时显示的文本</AlternateText>

        <Impressions>10</Impressions>

        <Keyword>Topic2</Keyword>

        <Caption>第2个图的标题</Caption>

    </Ad>

</Advertisements>

(2) 将两个图形文件p1.jpg和p2.jpg拷贝到网页文件WebForm1.aspx所在文件夹中。

(3) 在窗体中放置控件AdRotator,其属性Name= AdRotator1。单击其属性AdvertisementFile右侧标题为"…"的按钮,出现"选择XML文件"对话框,在对话框的"URL(U)"编辑框中选中控件AdRotator使用的XML文件"ads.xml"。

(4) 运行,可以看到一幅图,鼠标移到图中,变为手形,单击可以转到搜狐网站。单击浏览器刷新按钮,可以看到另一幅图。

XML 文件包含以下预定义的属性。只有 ImageUrl 属性是必需的:

l  ImageURL:显示在网页上的广告图片文件的URL 。

l  NavigateURL:单击AdRotator控件的广告图片,超级链接到指定页面的URL。

l  AlternateText: 图像不能正确显示时显示的文本,也用来作为鼠标停留在广告图片一段时间后,显示的提示信息。

l  Keyword:指定广告类别,可用于筛选特定类别广告。通过设置AdRotator的KeywordFilter属性以筛选出XML文件中相应类别的广告。 

l  Impression 指示广告的可能显示频率的数值。在 XML 文件中,所有 impression 值的总和不能超过 2,048,000,000 – 1。

10.8  Calender控件

Calendar控件在Web窗体页上显示一个月历,包括本月和该月前后各一周的日期,因此,一次总共显示六周。用户可使用该日历查看和选择日期。常用属性事件如下:

l  属性SelectionMode:控制日期的选择方式。默认设置为Day只允许用户选择一天;设置为DayWeek使用户可以选择一天或连续的一周;设置为DayWeekMonth使用户可以选择一天、一周或一个月。后两种选择方式只能选择连续的日期。

l  属性SelectDate:用户选择的日期,如允许选择1周或1个月,为选择的第1天。

l  属性SelectDates:用户选择的日期的集合。可通过其属性Count知道用户选择了多少天;用SelectDates[i]得到所选的第i个日期,第1个选择的日期索引号为0。

l  属性TodaysDate:今天的日期。

l  外观属性:见例子e10_8B中Calendar控件定义,有多个外观属性。可以通过设置控件不同部分的样式属性,定义Calendar控件的外观。例如可更改日历的颜色、尺寸、文本以及其它可视特性。外观属性采用默认值的显示效果见例子e10_8A,如右图。

l  事件OnSelectionChanged:用户改变选择日期时产生的事件。

例子e10_8A:Calendar控件最简单的用法如下,运行效果如右图。

<html>

<script language="C#" runat="server">

    void Date_Selected(object s, EventArgs e)//选择的日期改变时产生的事件

    {  Label1.Text = "所选日期是:" + Calendar1.SelectedDate.ToShortDateString();

    }

  </script>

<body>

    <form runat=server>

      <asp:Calendar id=Calendar1 OnSelectionChanged="Date_Selected" runat="server" />

      <asp:Label id=Label1 runat="server" />

    </form>

</body>

</html>

运行效果如上图。如果选择某一天,标签控件将显示为所作的选择。

例子e10_8B:本例网页显示了属性SelectionMode为不同值时Calendar控件的显示效果。

<html>

<script language="C#" runat="server">

    void Page_Load(Object Sender, EventArgs e)

{  Calendar1.SelectionMode =

(CalendarSelectionMode)lstSelMode.SelectedIndex;

       if (Calendar1.SelectionMode == CalendarSelectionMode.None)

              Calendar1.SelectedDates.Clear();

     }

     void Date_Selected(object s, EventArgs e)

      {  switch (Calendar1.SelectedDates.Count) {

         case (0):   //没有选择

           Label1.Text="没有选择!";

           break;

         case (1):   //选择1天

           Label1.Text="所选日期:" + Calendar1.SelectedDate.ToShortDateString();

           break;

         case (7):   //选择1周

           Label1.Text="所选周开始日期是:"

+ Calendar1.SelectedDate.ToShortDateString();

           break;

         default:    //选择1个月

           Label1.Text = "所选月开始日期是:"

+ Calendar1.SelectedDate.ToShortDateString();

           break;  

       }

     }

  </script>

  <body>

  <form runat=server>

      选择模式:

      <asp:DropDownList id="lstSelMode" runat=server AutoPostBack=true>

        <asp:ListItem Value="None" >不能选择</asp:ListItem>

        <asp:ListItem Selected Value="Day" >只能选择1天</asp:ListItem>

        <asp:ListItem Value="DayWeek" >可选1天或1周</asp:ListItem>

        <asp:ListItem Value="DayWeekMonth" >可选1天、1周或1月</asp:ListItem>

      </asp:DropDownList>

      <asp:Calendar id=Calendar1 onselectionchanged="Date_Selected"

        DayNameFormat="FirstLetter" Font-Name="Arial" Font-Size="12px"

        Height="180px" Width="200px" TodayDayStyle-BackColor="gainsboro"

        SelectorStyle-BackColor="gainsboro" TitleStyle-Font-Bold="True"

        OtherMonthDayStyle-ForeColor="gray" runat="server"

        TitleStyle-BackColor="gray" DayHeaderStyle-BackColor="gainsboro"

        TitleStyle-Font-Size="12px" SelectedDayStyle-BackColor="Navy"

        SelectedDayStyle-Font-Bold="True"/>

      <asp:Label id=Label1 runat="server"/>

    </form>

  </body>

</html>

运行效果如右图。可以从控件DropDownList中选择日历控件不同选择模式,选择模式包括:不能选择任何日期、只能选择1天、可选1天或1周、可选1天、1周或1月。注意控件DropDownList的属性AutoPostBack为true,因此DropDownList控件选择的改变产生的事件立刻发送到服务器端,重新生成页面,在Page_Load方法中选择了模式。

10.9   VS.Net实现留言板

例子e10_9:本例有两个网页。留言网页负责输入留言,包括输入用户名,留言主题,留言内容,用三个编辑框输入这些信息。输入完毕后,单击"提交"按钮,将留言存入数据库。单击"查看留言"按钮,可链接到另一个显示留言的网页。显示留言的网页包括一个DataGraid控件,用来显示所有的留言的用户名,主题,留言时间,还包括1列按钮,单击按钮,显示按钮所在行的留言内容。单击"返回主窗口"按钮,返回留言网页。下边是具体步骤:

(1)  用Access建立数据库LiuYanBan.mdb。创建LiuYanTable表,记录留言信息,该表包括留言编号字段LiuYanID,自动编号类型,主关键字;留言者姓名字段LiuYanName,文本,字段大小10,必填字段,默认值为空;留言标题字段LiuYanTitle,文本,字段大小30,必填字段,默认值为空;留言时间字段LiuYanTime,时间类型;留言内容字段LiuYanContent,备注字段,必填字段,默认值为空。增加若干数据。数据库文件路径为D:\asp\LiuYanBan.mdb,文件夹asp已设为Web网站宿主目录。步骤参见8.3节。

(2)  创建Web应用程序项目,项目名为e10_9。最终设计界面如图10.9。

(3)  放置4个Label控件到WebForm1窗体,属性Text分别修改为:留言板主窗体、用户名、留言主题、留言内容。具体位置如图10.9左图。

(4)  单击WebForm1属性Style右侧标题为"…"的按钮,打开"样式生成器"对话框,可以修改WebForm1各种风格。单击对话框左侧的各个选项:字体、背景、文本、位置、布局、边缘、列表、其它,可以按自己爱好修改相应的选项,这里不作修改,全部采用默认值。

(5)  放置3个TextBox控件到WebForm1窗体,属性Text都为空,ID=TextBox1编辑框用来输入用户名,ID=TextBox2编辑框用来输入留言主题,ID=TextBox3编辑框用来输入留言内容,TextBox3编辑框属性TextMode=MultiLine。由于此三项要求必须输入数据,因此应增加3个验证控件。请读者自己加入。具体位置如图10.9左图。

(6)  放置oleDbConnection控件到WebForm1窗体,其属性Name=oleDbConnection1,从其属性ConnectionString右侧下拉列表中选中新建连接,打开"数据连接属性"对话框,选择"提供程序"选项卡页,选中OLE DB提供程序为Microsoft Jet 4.0 OLE DB Provider,单击"下一步"按钮,在"连接"选项卡页中,选择数据库名称为D:\asp\ LiuYanBan.mdb,用户名称为Admin,选中"空白密码"多选框,单击"测试连接"按钮,应出现"测试连接成功"对话框。按"确定"按钮退出"数据连接属性"对话框。参见例e8_10B中的第一步。

(7)  在窗体中放置控件oleDbCommand,其属性Name=oleDbCommand1,从其属性Connection右侧的下拉列表中选中oleDbConnection1,指定oleDbCommand使用的数据连接对象。

(8)  放Button控件到WebForm1窗体,属性Text="提交留言"。按钮单击事件处理函数如下:

private void Button1_Click(object sender, System.EventArgs e)

{   oleDbConnection1.Open();//自动增加字段不必写入,自动产生

    oleDbCommand1.CommandText="Insert Into LiuYanTable (LiuYanName,LiuYanTitle,LiuYanTime,LiuYanContent) Values('" + TextBox1.Text + "', '" + TextBox2.Text + "','" + DateTime.Now + "','" + TextBox3.Text + "')";

    oleDbCommand1.ExecuteNonQuery();//执行SQL语句

    oleDbConnection1.Close();

    TextBox1.Text="";

    TextBox2.Text="";

    TextBox3.Text="";

}

(9)  单击VS.Net菜单"文件"|"添加新项(w)…"菜单项,出现"添加新项"对话框,在右侧选中"Web窗体",窗体名为:WebForm2.aspx,单击"打开"按钮,创建新窗体WebForm2。

(10)放置HyperLink控件到WebForm1窗体(留言窗体),属性Text="查看留言",单击属性NavigateUr右侧标题为"…"的按钮,打开"选择URL"对话框,从对话框中标题为"URL类型:"的ComboBox控件右侧下拉列表中选择"与根相关的"项,在标题为"e10_9的内容(C)"列表框中选中WebForm2.aspx。标题为"URL(U):" ComboBox控件的编辑框中出现如下内容:/e10_9/WebForm2.aspx。单击"确定"按钮退出对话框。见图10.9B

(11)在WebForm2窗体中放置控件oleDbDataAdapter,打开"数据适配器配置向导"对话框,单击"下一步"按钮,出现对话框如图8.12A,从ComboBox控件下拉列表中选中ACCESS.D:\ASP\LiuYanBan.mdb.Admin。参见例子e8_12中的第4步到第8步。

(12)单击图8.12A 中"下一步"按钮,出现对话框(未给出图)。在对话框中,选择标题为"使用 SQL 语句(S)"的单选按钮。

(13)单击"下一步"按钮,出现图8.12B对话框。单击对话框中"高级选项"按钮,打开"高级SQL选项"对话框,所有多选框都不选,单击"确定"按钮,退出"高级SQL选项"对话框。

(14)单击8.12B对话框中"查询生成器"按钮,在打开的"添加表"对话框(图8.12C但表名为LiuYanTable)中,选中LiuYanTable数据库表,单击"添加"按钮。关闭"添加表"对话框。

(15)在打开的标题为"查询生成器"对话框(图8.12D但数据库表是LiuYanTable)中,选中5个字段前的多选框,字段LiuYanID按降序排列,使新留言在前边显示,生成的SQL语句为:SELECT LiuYanContent, LiuYanID, LiuYanName, LiuYanTime, LiuYanTitle FROM LiuYanTable ORDER BY LiuYanID DESC。单击"确定"按钮退出。

(1)  在图8.12B的编辑框中自动增加以上SQL语句。单击图8.12B中的"下一步"按钮,出现对话框,列出所作的选择。单击"完成"按钮退出。可以看到新增的OleDbConnection和OleDbDataAdapter对象,并已配置好设置。

(16)选中组件oleDbDataAdapter1,单击VS.Net菜单"数据"|"生成数据集"菜单项。打开"生成数据集"对话框(图8.10E但数据库表名为LiuYanTable),不做修改,按"确定"按钮退出。自动增加数据集DataSet对象dataSet11。保存所有文件。

(17)放置控件dataView到WebForm2窗体,属性Name=dataView1。从控件dataView1属性Table右侧的下拉列表中,选中dataSet11中的LiuYanTable。

(18)在WebForm2窗体中放置2个Label控件,其属性Name分别为Label1、Label2,Label1的属性Text为空,用来显示留言,Label2的属性Text为:留言内容。

(19)放置DataGrid控件到WebForm2窗体,属性Name=DataGrid1。右击DataGrid1,在弹出的快捷菜单中,单击"自动套用格式"菜单项,在出现的对话框中选用自己喜欢的方案。

(20)右击控件DataGrid1,在弹出的快捷菜单中单击"属性生成器"菜单项,打开"DataGrid属性"对话框。在对话框左侧选中"常规",如图10.9C,从标题为"数据源(D):"的ComboBox控件下拉列表选中"dataView1",选中"显示页眉"、"显示页脚"、"允许排序"多选框。在"DataGrid属性"对话框左侧选中"列",如图10.9D,不选中"在运行时自动创建列"多选框,用单击标题为">"的按钮方法,将LiuYanName、LiuYanTitle、LiuYanTime字段及一个按钮列从"可用列(A)"列表框移到"选定的列(S)"列表框,表示DataGrid控件仅显示这3个字段。3个字段的"页眉文本"分别为:留言者姓名、留言标题、留言时间。增加的按钮列的列标题为:单击按钮查看留言,命令名为:ReadContent。在"DataGrid属性"对话框左侧选中"分页",选中"允许分页"多选框。单击"确定"按钮退出"DataGrid属性"对话框。

(21)为控件DataGrid1新增按钮列增加事件函数,DataGraid所有按钮都产生事件ItemCommand,根据命令名加以区分是哪一个按钮列发出的事件。事件处理函数如下:

private void DataGrid1_ItemCommand(object source,System.Web.UI.WebControls. DataGridCommandEventArgs e)

{   if (e.CommandName=="ReadContent")

    {   Label1.Text=dataSet11.Tables["LiuYanTable"].Rows[e.Item.ItemIndex]

["LiuYanContent"].ToString();

    }

}

(22)为Page_Load事件函数增加语句:

private void Page_Load(object sender, System.EventArgs e)

{   oleDbDataAdapter1.Fill(dataSet11);

    if(!Page.IsPostBack)

    {   DataGrid1.CurrentPageIndex=0;

        DataGrid1.DataBind();

    }

}

(23)为DataGraid1的DataGrid1_PageIndexChanged事件函数增加语句:

private void DataGrid1_PageIndexChanged(object source,

System.Web.UI.WebControls.DataGridPageChangedEventArgs e)

{   DataGrid1.CurrentPageIndex=e.NewPageIndex;

    DataGrid1.DataBind();

}

(24)放置HyperLink控件到WebForm2窗体(显示留言窗体),属性Text="增加留言",单击属性NavigateUr右侧标题为"…"的按钮,打开"选择URL"对话框,从对话框中标题为"URL类型:"的ComboBox控件右侧下拉列表选中"与根相关的"项,在标题为"e10_9的内容(C)"列表框中选中WebForm1.aspx。标题为"URL(U):" ComboBox控件的编辑框中出现如下内容:/e10_9/WebForm1.aspx。单击"确定"按钮退出对话框。参见图10.9B。

(25)运行,出现WebForm1,可以输入一条留言,单击提交按钮,再单击标题为"查看留言"的超级链接,转到WebForm2,单击DataGrid按钮列中的"查看留言"按钮,可以在标签控件Label1处看到留言,单击标题为"增加留言"的超级链接,转到WebForm1。

 

图10.9

 

                                图10.9B

 

                                图10.9C

 

图10.9D

习题

(1)      不使用VS.Net,用记事本编写两数相加求和的网页及显示一幅图像的网页。

(2)      10.1.4节例子中,修改程序,按照选中爱好的顺序,在标签控件中显示所选爱好。

(3)      用CheckBoxList控件选择标签控件字体的风格,如黑体、下划线、斜体、删除线等。

(4)      用RadioButtonList控件选择标签控件字体的名称,如宋体、楷体等。

(5)      用ListBox控件选择标签控件字体的风格,如黑体、下划线、斜体、删除线等。

(6)      用DropDownList控件选择标签控件字体的名称,如宋体、楷体等。

(7)      自定义数据验证控件CustomValidator要求用户必须输入偶数。

(8)      写出只能输入由26个大写字母组成的字符串的正则表达式。

(9)      写出只能输入由26个字母及数字组成的字符串的正则表达式。

(10)   将ArrayList类对象绑定到ListBox控件的列表。

(11)   将Student表的所有学生姓名绑定到RadioButtonList、CheckBoxList和ListBox控件。

(12)   修改例e10_4_4,Repeater2直接用Sql语句选择指定学生的学习成绩。

(13)   用DataList显示SdudentI数据库Student表的学号和姓名,并增加一个标题为"详细资料"的按钮,单击按钮,在其右侧显示该学生的详细资料及该学生的所有课程成绩。

(14)   在例子e10_6_3中,设置PageButtonCount="3",为什么分页导航栏只有2个按钮?

(15)   修改例子e10_6_3中的分页导航栏按钮为使用标题为"前页"和"后页"的按钮。

(16)   例子e10_6_6中,将按钮列标题该为如下形式:张三成绩、李四成绩等。

(17)   把本章中所有使用StudentI数据库Student表的例子改为使用微软SQL Server自带数据库Northwind中的表Employees。

(18)   参照网站留言板,修改10.9实现的留言板,使其实用化。

转载于:https://www.cnblogs.com/Aha-Best/p/10931762.html

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页