博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

GridView的自定义列,及几个常用事件

Posted on 2011-04-13 13:39  光照峋山  阅读(5982)  评论(0编辑  收藏  举报
GridView中的自定义列
GridView可以根据数据源自动生成列,但是如果我们需要自定义列的显示方式,让GridView的列完完全全的由我们自己来控制,我们就需要用到一种特殊的列――TemplateField。因为GridView生成的列都是一个字段一列,如果我们需要把两个字段合并为一列显示呢?我们可以使用模板列,指定包含标记和控件的模版,自定义列的布局和行为。
有2种添加自定义列的方法:
1.新建自定义列:打开右上角的Tag,Add New Column...接下来将类型选择为TemplateField。
               
2.将现有列转换为自定义列:打开右上角的Tag,Edit Columns...在打开的窗口中,选中你想要转换的现在列,然后点击右边底部的"Convert this field into a TemplateField".
在GridView上单击右键,在Edit Template中选择刚刚添加的模板列,出现列模版的编辑画面。其中HeaderTemplate――列的标头部分,FooterTemplate――脚注部分,ItemTemplate――此列主数据显示的内容,EditItemTemplate――此列处于编辑状态时如何显示,AlternatingItemTemplate――交替项显示的内容,也就是隔行分别以不同的风格显示。
                     
应用举例 1:
我们现在假设有一个表,其中有一个字段是username,我们现在产生一个自定义列,自定义列中包含此人的照片,同时我们假定照片的路径为image/username.jpg。我们编辑模版中的ItemTemplate,加入一个Image控件,然后右键点击Image控件,选择Edit DataBindings,在ImageUrl中设置Field Binding,设置Bound to 数据源中的某列,因为所有图片的路径和格式是相同的,唯有名字不同而已,所以我们这里选中username字段,在format中,要自己定义其格式,输入image/{0}.jpg, {0}代表的就是上面绑定的字段。下面有一个Two Way DataBinding (双向绑定)的复选框,一般采用单向(Eval),也就是说数值只从数据源传到页面上,如果双向绑定(Bind),对数据的修改可以回传到数据源之中。
在页面执行时,不同的行因为username不同,图片的名字也会做出相应的替换。点击确定,然后执行当前网页,我们就可以看到在我们的自定义列中显示出了用户的照片。
应用举例 2:
在数据库中,存储性别的时候,一般采用bit数据类型,存储为True或者False,在GridView自动生成列的时候,一般使用CheckedBoxField 列来显示bit类型的数据,显示在网页上就是一个单选框,如果是选中的(Checked),就是男的,否则就是女的。这样看起来很不直观,下面我们通过自定义列将性别显示为男、女。
在ItemTemplate中添加一个DropListDown控件,然后编辑它的数据绑定,Edit DataBinding,把SelectedValue属性绑定到性别列。
在DropListDown控件中选择 Edit Item,就是编辑其下拉列表的项,我们添加两个Item,一个的Text属性是男,Value属性为True,一个的Text属性为女,Value属性为False。因为DropDownList控件的显示文本和其值是可以不一样的,我们用数据绑定取到了性别这一列的值,True或者False,然后反映到DropDownList控件上,如果值为True,则显示Value属性为Ture的男。现在运行网页,在新添加的列中,显示的不再是单选框或者True、false这些没有含义的东西,而是以下拉列表的方式显示出了当前用户是 男还是女。
                                        
在自定义列中进行数据更新
假设数据库中有一个"权限"字段,值为0代表未审核用户,为1代表一般用户,为9则代表管理员用户。根据前面的自定义列的办法,通过对DropListDown的绑定,在网页中显示权限为 "管理员",而不是数字9。现在我不仅想要显示这个字段,还希望通过GridView的编辑功能来调整某个用户的权限,比如把一般用户更改为管理员。
同样的,我们可以通过DropDownList,把它的值返回给数据源来完成更新操作,不过这次需要自定义的是EditItemTemplate编辑模板了。在EditItemTemplate中设置的DropListDown控件,必须选中Two Way DataBinding,也就是数据双向绑定,才能返回数据。
另外我们需要对RowUpdating事件 (注意不是RowUpdated) 进行编码,编码如下:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//当前编辑的是哪行?
int index = GridView1.EditIndex;
//取得当前编辑行的GridViewRow对象
GridViewRow gvr = GridView1.Rows[index];
//在当前行中寻找DropListDown控件,editdrop为你在模板中拖入的DropDownList控件名
DropDownList dp = (DropDownList)gvr.FindControl("editdrop");
//将DropListDown的值赋给NewValues集合中的权限字段,rights为数据源中你想更新的字段名
e.NewValues["rights"] = dp.SelectedValue;
}
 
RowDataBound事件
在创建GridView控件时,必须先为GridView的每一行创建一个GridViewRow对象,创建每一行时,将引发一个RowCreated事件;当行创建完毕,每一行GridViewRow就要绑定数据源中的数据,当每一行完成绑定后,都将引发RowDataBound事件。
我们可以利用RowCreated事件来控制每一行的控件,同样地,可以利用RowDataBound事件来控制每一行绑定的数据,也就是让数据如何呈现给大家。
接着上面的例子,上面我们用DropListDown控件的DataBounding来表示出了中文的性别,但是毕竟不太美观,我们现在可以利用Label控件和RowDataBound事件来实现完美的中文性别显示。
首先,还是把性别列,设置为模板列,并添加一个Label控件,将Label控件绑定到数据源的性别段,然后我们在GridView控件属性的事件列表中双击RowDataBound,生成如下事件:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//判断当前行是否是数据行
if (e.Row.RowType == DataControlRowType.DataRow)
{
//用FindControl方法找到模板中的Label控件
Label lb1= (Label)e.Row.FindControl("Label1");
//因为RowDataBound是发生在数据绑定之后,所以我们可以判断Label绑定的数据,如果是True,就更改其text属性为男
if (lb1.Text== "True") //千万注意Ture的每个字母的大小写
lb1.Text = "";
else
lb1.Text
= "";
}
}
RowType可以确定GridView中行的类型,RowType是玫举变量DataControlRowType中的一个值。RowType取值包括 DataRow、Footer、Header、EmptyDataRow、Pager、Separator。很多时候,我们需要判断当前是否是数据行,通过如下代码来进行判断 :
if (e.Row.RowType == DataControlRowType.DataRow)
   
RowDeleting和RowDeleted事件
RowDeleting发生在删除数据之前,RowDeleted发生在删除数据之后。
使用RowDeleting事件,可以在真正删除前再次确认是否删除,可以通过设置GridViewDeleteEventArgs.Cancel=True来取消删除;也可以用于判断当前数据库记录数,如果只剩一条记录且数据库不能为空则提示并取消删除操作。
使用RowDeleted事件,可以在删除后,通过GridViewDeletedEventArgs的Exception属性判断删除过程中是否产生异常,如无异常,则可以显示类似于” 1 Records deleted” 之类的提示信息。
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
//取得当前行号,并取得当前行的GridViewRow对象
int index=e.RowIndex ;
GridViewRow gvr
=GridView1.Rows[index];
//取得当前行第二个单元格中的文字
str1 = gvr.Cells[1].Text;
//进行提示
Message.Text ="您将删除一个用户,其姓名为"+str1 ;
}
protected void GridView1_RowDeleted(object sender, GridViewDeletedEventArgs e)
{
//如果没有产生异常,则提示成功删除,否则提示删除失败
if (e.Exception == null)
Message.Text
+= "<br>您成功删除了"+str1 ;
else
Message.Text
+= "删除失败,请联系管理员";
}
       
RowEditing事件
在GridView中的行进入编辑模式之前,引发RowEditing事件,如果您需要在编辑记录前进行某些预处理,可以在这里操作。如果想取消对当前行的编辑,可以把GridViewEditEventArgs 对象的 Cancel 属性设置为 true即可。
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
//用NewEidIndex取得当前编辑的行号,然后获取gridviewrow对象
GridViewRow gvr = GridView1.Rows[e.NewEditIndex];
//判断,如果当前编辑行姓名栏为admin用户,则取消对当前行的编辑
if (gvr.Cells[1].Text =="admin")
e.Cancel
= true;
}
    
RowUpdating和RowUpdated事件
RowUpdating事件发生在更新数据源之前,RowUpdated发生在更新数据源之后。
我们可以在记录更新前利用RowUpdating做一些预处理工作,比如修改密码时,因为密码在数据库中不是明文存储,进行了hash,所以在更新密码前,应该生成其hash值,再进行更新操作。RowUpdated则可以检验更新是否成功。
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow gvr
= GridView1.Rows[GridView1 .EditIndex ];
//寻找输入密码的控件
TextBox tb1 = (TextBox)gvr.FindControl("tb_password");
//将此控件中的文本hash后,把password存入NewValues这个字典中
e.NewValues ["password"] =tb1.Text .GetHashCode().ToString () ;
}
protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
//如无异常,则更新成功
if (e.Exception == null)
Message.Text
+= "更新成功!";
}