【ASP.NET】第八课——GridView 控件的编辑功能优化,GridView控件中嵌套DropDownList控件

知识点:掌握 GridView 的编辑、高亮显示的功能 、GridView控件中嵌套DropDownList控件获取数据源。

           【ASP.NET】第七课——数据绑定和 GridView 控件的使用 重点学习了 ASP.NET 中数据绑定的概念、数据绑定控件 GridView 的基本用法。使用它 能快速展示数据,并且能实现分页、删除操作。

           GridView 的功能很强大,除了能分页、删除外,我们将继续学习它的编辑和高亮显示的 功能。GridView 的编辑如同 Excel 一样方便,在编辑状态下,提供文本框或者下拉列表框供用 户编辑新的数据,然后更新数据到数据库中。


1、GridView控件的编辑

           对数据常用的操作除了展示、删除外,还需要能进行修改。GridView 对数据的修改如同 Excel 电子表格一样方便。

示例练习1:给GridView控件添加“编辑”按钮

要求:每一行数据后面,增加一个“编辑”按钮。

前提:在【ASP.NET第七课】的基础之上完成。

第一步,打开项目:在VS中打开已有项目【WebApplication7】,打开方法:找到项目在电脑上存放的位置,双击WebApplication7.sln文件,即可在VS中打开项目。

第二步,增加“编辑”列:打开WebForm4.aspx文件,切换到【拆分】视图,打开GridView控件的【字段】窗口,点击【可用字段】里的CommandField,然后点击前面的按钮,然后点击【编辑、更新、取消】→再点击【添加】,会自动增加一个【编辑、更新、取消】字段。

第三步,设置字段属性:HeaderText属性设置为:编辑,ButtonType属性设置为:Button,然后单击【确定】即可。

第四步,添加RowEditing事件:如果直接运行,点击每一行数据后面的“编辑”时,报错。提示:GridView“GridView1”激发了未处理的事件“RowEditing”。因此我们先给字段添加好对应的事件。添加方法,选中GridView控件后,在属性面板切换到【事件】,找到RowEditing,然后双击,进入该事件的代码编写,(我们这里先不写具体的事件代码,运行测试一下效果。)

第五步,运行测试:当前页面下,单击鼠标右键,然后单击【在浏览器中预览】,查看效果。

  • 问题分析:当我们点击GridView控件的【编辑】按钮时,需要点击第二次时,页面才会变成可编辑状态。
  • 问题原因:GridView控件第一次点击只获取选中行的索引,第二次点击才变成可编辑状态。
  • 解决办法:获取选中行的索引,并赋值给控件,使其变成可编辑索引

第六步,编写RowEditing事件:打开WebForm4.aspx.cs文件,找到RowEditing事件,编写代码

        protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
        {
            //使用e.NewEditIndex获取新的编辑索引,将其赋值给GridView1编辑行的索引
            this.GridView1.EditIndex = e.NewEditIndex;
            //重新绑定数据
            BindScar();
        }

运行测试:

 

示例练习2:“编辑”状态下,设置“删除”按钮不可用

要求:行数据在“编辑”状态下,要求“删除”按钮不可用

第一步,将“删除”列改为模板列:我们在后面需要通过ID找到每一行所对应的“删除”控件,但是,在源代码里CommandField控件是没有ID的(自己添加会报错)。因此,我们将CommandField列修改为TemplateField模板列。

修改方法:选中GridView控件后,打开GridView控件的【字段】窗口,点击【选定的字段】里的“删除数据”,然后点击【将此字段转换为TemplateField】,然后点击【确定】。

查看源代码:此时再看源代码,自动生成了ID属性:LinkButton1。

第二步,添加RowDataBound事件:选中GridView控件后,在属性面板切换到【事件】,找到RowDataBound,然后双击,进入该事件的代码编写,

第三步,编写RowDataBound事件:自动打开WebForm4.aspx.cs文件,光标定位到到RowDataBound事件,编写事件代码:

        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            //变量e,是在建造行对象时产生的事件描述数据,它里面包含正在建造的当前行对象的信息,通过它我们可以取得正在建造的行对象和行对象中的单元格对象,并可以取得或设置这些对象相应的属性。
            //①断当前行是不是数据绑定行
                  //e.Row.RowType属性,是指当前行的类型(页眉、页脚、数据行、分页行、分隔符)
                 //DataControlRowType 是GridView的行的类型集合(枚举类型) , 其中的DataRow是数据绑定行,也就是我们判断经常使用到,他表示我们操作的对象只是绑定的数据部分,而不是页脚、页眉之类的部分
            if ( e.Row.RowType == DataControlRowType.DataRow)
            {
                //②找到“删除”控件
                Control c = e.Row.Cells[6].FindControl("LinkButton1");//e.Row:获取数据绑定的行,在行中的单元格中找删除按钮
                LinkButton lbtn = (LinkButton)c;//将控件向下转换
                //③判断当前行,是否处于编辑状态
                int i = (int)e.Row.RowState;//e.Row.RowState属性,它表示正在建造的行对象的状态(普通状态Normal、交替状态Alternate、编辑状态、选中状态等)。仅当数据行处理普通状态和交替状态时起作用,在编辑和选中状态不是不起作用的(编辑状态下,数据不是显示在单元格的Text中,而是显示在单元格的控件中的)。
                if( i == 4 || i ==5)//通过代码测试Response.Write("该行的状态是:" + i + "<br/>");总结:当i=4或者5时,处于编辑状态)
                {//该行处于编辑状态
                    lbtn.Enabled = false;//④设置控件的编辑状态为假
                }
                else
                {
                    lbtn.Enabled = true;
                }
            }
        }

第四步,运行测试:

 

示例练习3:“编辑”状态下,设置“点击量”不可编辑

要求:行数据在“编辑”状态下,要求“点击量”的数据,不允许编辑

实现方法:设置控件的ReadOnly属性为true

修改后的代码:<asp:BoundField DataField="Click" HeaderText="点击量" ReadOnly="true" />

运行测试:

案例完善:把“编号”列,也设置为不可编辑。

 

示例练习4:“取消”操作

要求:行数据在“编辑”状态下,修改后,点击“取消”按钮,恢复本行数据的原有信息。

实现方法:选中GridView控件后,在属性面板切换到【事件】,找到RowCancelingEdit,然后双击,进入该事件的代码编写,

        //用户点击取消时
        protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
        {
            this.GridView1.EditIndex = -1;//因为GridView控件的索引,都是从0行开始的。这里设置为-1,实际上就是说当前在编辑 第 -1 行,相当于一个取消编辑状态的效果。
            //重新绑定数据
            BindScar();
        }

运行测试:


 

示例练习5:“编辑”状态下,设置“汽车图片”以上传控件的形式出现

要求:行数据在“编辑”状态下,要求“汽车图片”的数据,允许以上传控件展示,供用户修改

第一步,将“汽车图片”列改为模板列:选中GridView控件后,打开GridView控件的【字段】窗口,点击【选定的字段】里的“汽车图片”,然后点击【将此字段转换为TemplateField】,然后点击【确定】。

此时的源代码:

第二步,修改为模板列:默认情况是出现TextBox控件,修改 EditItemTemplate 模板,将默认的文本框修改为上传文件控件。

①删除文本框控件:<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("picture") %>'></asp:TextBox>

②在删除位置,添加FileUpload控件:<asp:FileUpload ID="FileUpload1" runat="server" />

此时运行测试,点击“编辑”后,观察“汽车图片”列的信息,采用的是FileUpload控件,允许用户自行浏览文件。

 

示例练习6:“编辑”状态下,设置“品牌名称”以下拉列表框展示

要求:行数据在“编辑”状态下,要求“品牌名称”的数据以下拉列表框展示,供用户选择

第一步,将“品牌”列改为模板列:选中GridView控件后,打开GridView控件的【字段】窗口,点击【选定的字段】里的“品牌名称”,然后点击【将此字段转换为TemplateField】,然后点击【确定】。

此时源代码:

                    <asp:TemplateField HeaderText="品牌名称">
                        <EditItemTemplate>
                            <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("BrandName") %>'></asp:TextBox>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="Label1" runat="server" Text='<%# Bind("BrandName") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>

第二步,修改为模板列:默认情况是出现文本框控件,修改 EditItemTemplate 模板,将默认的文本框修改为下拉列表框。

①删除文本框控件:<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("BrandName") %>'></asp:TextBox>

②在删除位置,添加DropDownList控件:<asp:DropDownList ID="DropDownList1" runat="server"></asp:DropDownList>

此时运行测试,点击“编辑”后,发现品牌名称列的信息,采用的是DropDownList控件,但是没有数据。需要我们给控件绑定数据源,也就是在GridView控件里内嵌DropDownList绑定数据源

第三步,添加方法:编写后置代码,添加方法,实现查询所有品牌的功能。点击鼠标右键,然后点击【查看代码】,进入后置代码文件WebForm4.aspx.cs,声明一个方法,用来获取品牌的数据源。

        //声明一个方法,绑定品牌名称
        public DataTable  bindBrand()
        {
            string sql = "select * from Brand";
            DataSet ds = DBHelper.getDataSet(sql);
            return ds.Tables[0];
        }

第四步,给控件绑定数据源:打开WebForm4.aspx文件,给DropDownList控件,绑定数据源,并设置相关属性。

属性说明:

  • DataSource:获取数据源。
  • DataTextField:设置为列表项提供文本内容的数据源字段。用作显示内容,一般给显示在界面,给用户看。
  • DataValueField:设置为各列表项提供值的数据源字段。放唯一性的字段值,一般是主键。
  • SelectedValue:获取控件选择值。
                    <asp:TemplateField HeaderText="品牌名称">
                        <EditItemTemplate>
                            <asp:DropDownList ID="DropDownList1" runat="server"  DataSource='<%#bindBrand()%>'  DataTextField="BrandName" DataValueField="BrandId" SelectedValue='<%#Eval("BrandId") %>'></asp:DropDownList>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="Label1" runat="server" Text='<%# Bind("BrandName") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>

第五步,运行测试:

 

示例练习7:“更新”操作

要求:行数据在“编辑”状态下,修改后,点击“更新”按钮,将新的数据信息保存到数据库并显示。

实现方法:

第一步,添加DataKeyNames属性:选中GridView控件后,在属性面板切找到DataKeyNames属性,设置为CarId。DataKeyNames 属性指定表示数据源主键的字段。当设置了 DataKeyNames 属性时,GridView 控件用来自指定字段的值填充它的 DataKeys 集合,这提供了一种访问每个行的主键的便捷方法。

第二步,添加RowUpdating事件:选中GridView控件后,在属性面板切换到【事件】,找到RowUpdating,然后双击,进入该事件的代码编写。

 

        protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {
            // 要更新数据库,需要从GridView来获取每一个字段的值
            //获取编号CarId 
            int txtCarId = int.Parse(this.GridView1.DataKeys[e.RowIndex].Value.ToString());
            //获取汽车名称txtCarName
            string txtCarName = ((TextBox)(this.GridView1.Rows[e.RowIndex].Cells[1].Controls[0])).Text;
            //获取品牌名称对应的品牌ID,ddlBrandId
            int ddlBrandId = int.Parse(((DropDownList)(this.GridView1.Rows[e.RowIndex].FindControl("DropDownList1"))).SelectedValue);
            //获取上传的文件名称,fuPicture
            string fuPicture = ((FileUpload)(this.GridView1.Rows[e.RowIndex].FindControl("FileUpload1"))).FileName;     
            //获取官方价格txtPrice
            string txtPrice = ((TextBox)(this.GridView1.Rows[e.RowIndex].Cells[4].Controls[0])).Text;
            //这里省略了对FieldUpload控件上传功能的实现,运行测试的时候, 直接使用项目中已有的图片
            //更新数据的sql语句
            string sql = string.Format("update Scar set CarName='{0}',BrandId='{1}',Picture='{2}',OfficialPrice='{3}' where CarId='{4}'", txtCarName, ddlBrandId, fuPicture, txtPrice, txtCarId);
            int i = DBHelper.GetExecute(sql);
            if (i > 0)
            {
                this.GridView1.EditIndex = -1;//取消编辑状态的效果。
                //重新绑定数据
                BindScar();
            }
            else
            {
                Response.Write("修改失败");
            }
        }

运行测试:

案例思考:

1、本示例的代码稍显冗余,如何简化一下?

2、编辑状态下,用户如果没有浏览新的图片文件,会丢失原有的图片,如何解决这个问题?

  • 在前台图片模板里,增加一个隐藏控件
                    <asp:TemplateField HeaderText="汽车图片">
                        <EditItemTemplate>
                            <asp:FileUpload ID="FileUpload1" runat="server" />
                            <asp:HiddenField ID="HiddenField1" runat="server"  Value='<%# Eval("Picture")%>' />
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Image ID="Image1" runat="server" ImageUrl='<%# Eval("picture", "~/Images/{0}") %>' />
                        </ItemTemplate>
                    </asp:TemplateField>
  • 后台代码,增加一个判断:
            //获取原有的图片文件名称,其保存在隐藏文件里
            string hfPicture =  ((HiddenField)(this.GridView1.Rows[e.RowIndex].FindControl("HiddenField1"))).Value;
            //判断用户是否浏览新的文件
            if (fuPicture == string.Empty)//如果用户没有浏览新的文件,则将原有文件名称赋值给控件
            {
                fuPicture = hfPicture;
            }

3、本案例没有做控件上传功能,测试时用的是项目中已有的图片素材。如果要增加上传功能,如何实现?

 

 

 

 

 

 

2、高亮显示鼠标悬浮的行数据

          高亮显示鼠标悬浮的行数据其实就是改变行的背景色。在 css 中,backgroundColor 属性用 于设置对象的背景色。使用 JavaScript 时,我们可以通过“对象.style.backgroundColor”来 获得或者设置某对象的背景色。

          我们只需要给高亮显示的行添加两个客户端事件“onmouseover”和“onmouseout”,当鼠标 悬浮在 GridView 的某一行时,改变背景颜色,当鼠标离开时,恢复以前的背景颜色。我们需要在表格中的每一行添加这两个事件,但是 GridView 中的行是绑定生成的,只能通过 “OnRowDataBound”事件的处理程序,实现 GridView 在绑定行的时候,添加当前行的 “onmouseover”和“onmouseout”事件。

示例练习8:“高亮显示”鼠标悬浮的行数据

要求:鼠标悬浮在数据行时,高亮显示该行数据。

实现方法:选中GridView控件后,在属性面板切换到【事件】,找到RowDataBound,然后双击,进入该事件的代码编写。

运行测试:

 

3、继续完善GridView控件展示数据

示例练习9:隐藏列

要求:将编号列,进行隐藏。

实现方法:打开GridView控件的【字段】窗口,点击【选定的字段】里的编号,设置Visible属性为False,然后点击【确定】。

运行测试:

 

3.1  TemplateField

         GridView控件中的一个重要的列类型是TemplateField,它可以使用模板完全定制列的内容。TemplateField只是一个可以添加其他内容的容器,如文本、HTML控件甚或ASP.NET控件。TemplateField提供了6个不同的模板,用于定制列的指定区域,或创建列中的单元格能进入的模式,如编辑模式。

                模  板  名

                                  说    明

ItemTemplate

用于显示数据绑定控件的TemplateField中的一项

AlternatingItemTemplate

用于显示TemplateField的替换项

EditItemTemplate

用于显示编辑模式下的TemplateField项

InsertItemTemplate

用于显示插入模式下的TemplateField项

HeaderTemplate

用于显示TemplateField的标题部分

FooterTemplate

用于显示TemplateField的脚标部分

        添加了TemplateField字段后,就会在GridView中添加一个新的<asp:TemplateField>标记,

<asp:TemplateField></asp:TemplateField>

 

示例练习10:增加“全选”列

要求:增加一列“全选”

实现方法:

第一步,增加TemplateField列:打开GridView控件的【字段】窗口,点击【可用字段】里的TemeplateField,然后点击【添加】,会自动增加一个【TemeplateField】字段,在选定的字段里,点击,调整顺序到第一个。

第二步,修改源代码:将WebForm4.aspx文件,切换到【源】视图,修改控件

默认添加的控件源代码:

修改控件源代码:

                    <asp:TemplateField>
                        <HeaderTemplate>
                            <asp:CheckBox ID="CheckBox1" runat="server" />全选
                        </HeaderTemplate>
                        <ItemTemplate>
                            <asp:CheckBox ID="CheckBox2" runat="server" />
                        </ItemTemplate>
                    </asp:TemplateField>

运行测试:

案例思考:这里只是增加了“全选”的样式,但没有“全选”的功能,如何实现“全选”功能?

 

 

本案例完整代码:

前台代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm4.aspx.cs" Inherits="WebApplication7.WebForm4"  %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>GridView—王迪</title>
    <style type="text/css">
        img{
            width:100px;
            height:80px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" AllowPaging="True" CellPadding="4" ForeColor="#333333" GridLines="None" OnPageIndexChanging="GridView1_PageIndexChanging" OnRowDeleting="GridView1_RowDeleting" PageSize="3" OnRowDataBound="GridView1_RowDataBound" OnRowEditing="GridView1_RowEditing" OnRowCancelingEdit="GridView1_RowCancelingEdit" DataKeyNames="CarId" OnRowUpdating="GridView1_RowUpdating" >
                <AlternatingRowStyle BackColor="White" />
                <Columns>
                    <asp:TemplateField>
                        <HeaderTemplate>
                            <asp:CheckBox ID="CheckBox1" runat="server" />全选
                        </HeaderTemplate>
                        <ItemTemplate>
                            <asp:CheckBox ID="CheckBox2" runat="server"  />
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:BoundField DataField="CarId" HeaderText="编号"  ReadOnly="true" Visible="False"  />
                    <asp:BoundField DataField="CarName" HeaderText="汽车名称" />
                    <asp:TemplateField HeaderText="品牌名称">
                        <EditItemTemplate>
                            <asp:DropDownList ID="DropDownList1" runat="server" DataSource='<%#bindBrand()%>'  DataTextField="BrandName" DataValueField="BrandId" SelectedValue='<%#Eval("BrandId") %>'></asp:DropDownList>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="Label1" runat="server" Text='<%# Bind("BrandName") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="汽车图片">
                        <EditItemTemplate>
                            <asp:FileUpload ID="FileUpload1" runat="server" />
                            <asp:HiddenField ID="HiddenField1" runat="server"  Value='<%# Eval("Picture")%>' />
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Image ID="Image1" runat="server" ImageUrl='<%# Eval("picture", "~/Images/{0}") %>' />
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:BoundField DataField="OfficialPrice" HeaderText="官方报价" DataFormatString="{0:C}" />
                    <asp:BoundField DataField="Click" HeaderText="点击量"  ReadOnly="true" />
                    <asp:TemplateField HeaderText="删除数据" ShowHeader="False">
                        <ItemTemplate>
                            <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" CommandName="Delete" Text="删除"></asp:LinkButton>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:HyperLinkField DataNavigateUrlFields="CarId" DataNavigateUrlFormatString="~/detailCar.aspx?CarId={0}" HeaderText="详细" Text="详细" />
                    <asp:CommandField HeaderText="编辑" ButtonType="Button" ShowEditButton="True" />
                </Columns>
                <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
                <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
                <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
                <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
                <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
                <SortedAscendingCellStyle BackColor="#FDF5AC" />
                <SortedAscendingHeaderStyle BackColor="#4D0000" />
                <SortedDescendingCellStyle BackColor="#FCF6C0" />
                <SortedDescendingHeaderStyle BackColor="#820000" />
            </asp:GridView>
        </div>
    </form>
</body>
</html>

后置代码:

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;


namespace WebApplication7
{
    public partial class WebForm4 : System.Web.UI.Page
    {
        public void BindScar()//声明一个绑定方法
        {
            //创建查询语句
            string sql = "select * from Scar ,Brand where Scar.BrandId = Brand.BrandId";
            //使用DBHelper类的getDataSet()方法,获得查询结果,返回的是一个数据集,将其放在DataSet对象里。需要引用命名空间System.Data;
            DataSet ds = DBHelper.getDataSet(sql);
            //将ds的第一张表赋值给DataTable
            DataTable dt = ds.Tables[0];
            //将数据绑定到GridView1里
            this.GridView1.DataSource = dt;
            //调用控件的DataBind方法
            this.GridView1.DataBind();
        }

        //声明一个方法,绑定品牌名称
        public DataTable bindBrand()
        {
            string sql = "select * from Brand";
            DataSet ds = DBHelper.getDataSet(sql);
            return ds.Tables[0];
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            //BindScar();
            if (!IsPostBack)
            {
                BindScar();
            }
        }

        protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            //获取用户选中的行所对应的编号,并存在变量里
            int checkId = int.Parse(this.GridView1.Rows[e.RowIndex].Cells[0].Text);
            //创建删除语句,用+将字符串和变量连接
            string sql = "delete from Scar where CarId=" + checkId ;
            //将DBHelper类的执行结果,存到整型变量里
            int i = DBHelper.GetExecute(sql);
            if (i > 0)
            {
                Response.Write("<script>alert('删除成功')</script>");
                //ClientScript.RegisterStartupScript(this.GetType(), "DelSuccess", "<script>alert('删除成功')</script>");
                //重新绑定一次数据
                BindScar();
            }
        }

        protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            //获取新的页面,赋值给控件的PageIndex属性
            this.GridView1.PageIndex = e.NewPageIndex;
            //重新绑定一次数据
            BindScar();
        }

        protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
        {
            //使用e.NewEditIndex获取新的编辑索引,将其赋值给GridView1编辑行的索引
            this.GridView1.EditIndex = e.NewEditIndex;
            //重新绑定数据
            BindScar();
        }

        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
                //变量e,是在建造行对象时产生的事件描述数据,它里面包含正在建造的当前行对象的信息,通过它我们可以取得正在建造的行对象和行对象中的单元格对象,并可以取得或设置这些对象相应的属性。
                //①断当前行是不是数据绑定行
                //e.Row.RowType属性,是指当前行的类型(页眉、页脚、数据行、分页行、分隔符)
                //DataControlRowType 是GridView的行的类型集合(枚举类型) , 其中的DataRow是数据绑定行,也就是我们判断经常使用到,他表示我们操作的对象只是绑定的数据部分,而不是页脚、页眉之类的部分
                if (e.Row.RowType == DataControlRowType.DataRow)
                {
                      //为了实现鼠标离开时恢复背景色,使用currentcolor变量保存行本来的背景色
                     e.Row.Attributes.Add("onmouseover", "currentcolor=this.style.backgroundColor; this.style.backgroundColor='#6699ff';"); 
                     e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=currentcolor;");
                     //②找到“删除”控件
                     Control c = e.Row.Cells[6].FindControl("LinkButton1");//e.Row:获取数据绑定的行,在行中的单元格中找删除按钮
                    LinkButton lbtn = (LinkButton)c;//将控件向下转换
                    //③判断当前行,是否处于编辑状态
                    int i = (int)e.Row.RowState;//e.Row.RowState属性,它表示正在建造的行对象的状态(普通状态Normal、交替状态Alternate、编辑状态、选中状态等)。仅当数据行处理普通状态和交替状态时起作用,在编辑和选中状态不是不起作用的(编辑状态下,数据不是显示在单元格的Text中,而是显示在单元格的控件中的)。
                    if (i == 4 || i == 5)//通过代码测试Response.Write("该行的状态是:" + i + "<br/>");总结:当i=4或者5时,处于编辑状态)
                    {//该行处于编辑状态
                        lbtn.Enabled = false;//④设置控件的编辑状态为假
                    }
                    else
                    {
                        lbtn.Enabled = true;
                    }
                }
            
        }

        protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
        {
            this.GridView1.EditIndex = -1;//因为GridView控件的索引,都是从0行开始的。这里设置为-1,实际上就是说当前在编辑 第 -1 行,相当于一个取消编辑状态的效果。
            //重新绑定数据
            BindScar();
        }

        protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {
            // 要更新数据库,需要从GridView来获取每一个字段的值
            //获取编号CarId 
            int txtCarId = int.Parse(this.GridView1.DataKeys[e.RowIndex].Value.ToString());
            //获取汽车名称txtCarName
            string txtCarName = ((TextBox)(this.GridView1.Rows[e.RowIndex].Cells[2].Controls[0])).Text;
            //获取品牌名称对应的品牌ID,ddlBrandId
            int ddlBrandId = int.Parse(((DropDownList)(this.GridView1.Rows[e.RowIndex].FindControl("DropDownList1"))).SelectedValue);
            //获取上传的文件名称,fuPicture
            string fuPicture = ((FileUpload)(this.GridView1.Rows[e.RowIndex].FindControl("FileUpload1"))).FileName;
            //获取原有的图片文件名称,其保存在隐藏文件里
            string hfPicture =  ((HiddenField)(this.GridView1.Rows[e.RowIndex].FindControl("HiddenField1"))).Value;
            //判断用户是否浏览新的文件
            if (fuPicture == string.Empty)//如果用户没有浏览新的文件,则将原有文件名称赋值给控件
            {
                fuPicture = hfPicture;
            }
            //获取官方价格txtPrice
            string txtPrice = ((TextBox)(this.GridView1.Rows[e.RowIndex].Cells[5].Controls[0])).Text;
            //这里省略了对FieldUpload控件上传功能的实现,运行测试的时候, 直接使用项目中已有的图片
            //更新数据的sql语句
            string sql = string.Format("update Scar set CarName='{0}',BrandId='{1}',Picture='{2}',OfficialPrice='{3}' where CarId='{4}'", txtCarName, ddlBrandId, fuPicture, txtPrice, txtCarId);
            int i = DBHelper.GetExecute(sql);
            if (i > 0)
            {
                this.GridView1.EditIndex = -1;//取消编辑状态的效果。
                //重新绑定数据
                BindScar();
            }
            else
            {
                Response.Write("修改失败");
            }
        }
    }
}

 

 

4、DetailsView 控件

         GridView 和 DetailsView 控件一般合作使用,实现“列表/详细”功能。DetailsView 控件和 GridView 控件有很多相似之处,但是 DetailsView 控件有添加数据的功能,而 GridView 没有。

         DetailsView 控件以表格形式(table 标签)一次仅显示数据源的单条记录,并且 table 标 签下的每行(tr 标签)表示记录中的一个字段。DetailsView 控件支持数据的编辑、插入和删除 操作,并可以轻松地设置分页功能,但是 DetailsView 控件本身不支持数据排序。

 

示例练习11:使用DatailsView控件显示数据

要求:使用 DetailsView 控件完成车型的详细页面DetailCar.aspx。

实现方法:

第一步,添加DatailsView控件:打开“DetailCar.aspx”文件,从工具箱中找到DatailsView控件,将其拖拽到适合的位置。

第二步,绑定数据源:在“DetailCar.aspx”文件中,单击鼠标右键,然后点击【查看代码】,会打开“DetailCar.aspx.cs”文件,我们声明一个方法,用来绑定数据源。

注意:方法的返回值是集合,虽然 DetailsView 控件一次仅显示数据源的单条记录,但是绑定 到 DetailsView 控件的数据源仍然是表格或者是集合。

        //声明一个方法,用来绑定数据源
        public void showData()
        {
            //创建查询语句
            string sql = "select * from Scar ,Brand where Scar.BrandId = Brand.BrandId";
            //使用DBHelper类的getDataSet()方法,获得查询结果,返回的是一个数据集,将其放在DataSet对象里。需要引用命名空间System.Data;
            DataSet ds = DBHelper.getDataSet(sql);
            //将ds的第一张表赋值给DataTable
            DataTable dt = ds.Tables[0];
            //将数据绑定到DetailsView1里
            this.DetailsView1.DataSource = dt;
            //调用控件的DataBind方法
            this.DetailsView1.DataBind();
        }

第三步,调用绑定方法:在“DetailCar.aspx.cs”文件的Page_Load方法里,调用刚才写的方法。

第四步,运行测试:直接将“DetailCar.aspx”文件在浏览器中运行测试

注意:在没有指定的时候,模型显示数据集合中第一条记录的信息。

案例思考:

1、完善DatailsView控件显示数据,如中文显示字段名、增加编辑功能等。

2、使用DatailsView输出指定行数据。

完善:示例练习11

要求:在详细页面DetailCar.aspx显示对应的车型信息。

方法:在绑定数据源的时候,通过查询语句,只绑定单行数据。修改第二步的操作即可。

运行测试:

后置文件代码:

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication7
{
    public partial class detailCar : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //利用Request对象的QueryString属性,获取上一个页面的信息
            string str = Request.QueryString["CarId"];
            Response.Write("查看的车型编号是:" + str);
            //调用绑定方法
            showData();
        }

        //声明一个方法,用来绑定数据源
        public void showData()
        {
            //获取上一个页面传过来的CarId数据(主键列)
            string CarId = Request.QueryString["CarId"];
            //创建查询语句(通过主键,只查询一条信息)
            string sql = "select * from Scar where CarId="+CarId;
            //使用DBHelper类的getDataSet()方法,获得查询结果,返回的是一个数据集,将其放在DataSet对象里。需要引用命名空间System.Data;
            DataSet ds = DBHelper.getDataSet(sql);
            //将ds的第一张表赋值给DataTable
            DataTable dt = ds.Tables[0];
            //将数据绑定到DetailsView1里
            this.DetailsView1.DataSource = dt;
            //调用控件的DataBind方法
            this.DetailsView1.DataBind();
        }
    }
}

 

 

本课总结:

  • RowDataBound 事件在 GridView 控件中的某个行被绑定到一个数据记录时发生。此事件通 常用于在某个行被绑定到数据时修改该行的内容。
  • RowEditing 事件在单击 GridView 控件内某一行的 Edit 按钮时发生,实现使所在的行处 于编辑状态的功能。
  • RowUpdating 事件在单击 GridView 控件内某一行的 Update 按钮时发生,实现把新的数据 更新到数据库中的功能。
  • RowCancelingEdit 事件在单击 GridView 控件内某一行的 Cancel 按钮时发生,实现使 GridView 控件退出编辑模式。
  • 与修改 GridView 的显示界面类似,在 DetailsView 中可以通过修改 Fields 属性来增加和减 少显示的字段、修改字段的标题,使用模板页指定 DetailsView 控件处于不同状态下的内容。
  • DetailsView 有三种显示状态:Edit 编辑状态、Insert 添加状态和 ReadOnly 只读状态,三 种状态保存在枚举类型 DetailsViewMode 中。调用 DetailsView 的 ChangeMode 方法并传递 状态枚举值时,将 DetailsView 控制切换到指定的模式。

 

 

 

 

 

===========这里是结束分割线=============

  • 16
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逍遥小丸子

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值