原文地址:
http://www.codeproject.com/useritems/EditGridviewCells.asp[原文源码下载][译者改后源码下载]
[翻译]在GridView中针对鼠标单击的某一独立单元格进行编辑
原文发布日期:2007.04.07
作者:
DeclanBright
翻译:
webabcd介绍
ASP.NET的GridView控件允许你通过设置它的EditIndex属性来编辑数据行,此时整个数据行都处于编辑模式。如果你在EditItemTemplate的一些列中使用了DropDownList控件,那么你也许不希望整个数据行都处于编辑模式。因为,如果每一个DropDownList控件都有很多选项的话,那么一次加载所有DropDownList控件的所有选项就会导致页面执行缓慢。
另外,如果你的数据行的编辑模式需要占用更多的空间的话,那么针对每一个独立的单元格进行编辑要优于针对整个数据行进行编辑。这里,我将示范如何实现这样的功能,又如何去处理事件验证(eventvalidation)。
背景
本文基于我之前写的一篇文章:
GridView和DataList响应单击数据行和双击数据行事件。如果你不知道如何让GridView响应单击数据行事件,那么你可以在阅读本文之前先看看这篇文章。
编辑某一个独立的GridView单元格。
我所演示的这个GridView有一个不可见的asp:ButtonField控件,它处于GridView的第一列,名为“SingleClick”。它用于给GridView的数据行增加单击事件。
<Columns>
<asp:ButtonFieldText="SingleClick"CommandName="SingleClick"Visible="False"/>
</Columns>
其它每一列的ItemTemplate中有一个可见的Label控件和一个不可见的TextBox或DropDownList控件。为了方便,我们称Label为显示控件,TextBox或DropDownList为编辑控件。
<asp:TemplateFieldHeaderText="Task">
<ItemTemplate>
<asp:LabelID="DescriptionLabel"runat="server"Text='<%#Eval("Description")%>'></asp:Label>
<asp:TextBoxID="Description"runat="server"Text='<%#Eval("Description")%>'Width="175px"visible="false"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
这里的办法就是用显示控件来显示数据,当单元格所包含的显示控件被单击的时候,则把显示控件的Visible属性设置为false并且把编辑控件的Visible属性设置为true。这里不用使用EditItemTemplat。
在RowDataBound事件内循环为每一数据行的每一单元格增加单击事件。使用单元格在数据行中的索引作为事件参数,这样在单元格触发了单击事件后我们就可以知道到底是哪个单元格被单击了。
protectedvoidGridView1_RowDataBound(objectsender,GridViewRowEventArgse)
{
if(e.Row.RowType==DataControlRowType.DataRow)
{
//从第一个单元格内获得LinkButton控件
LinkButton_singleClickButton=(LinkButton)e.Row.Cells[0].Controls[0];
//返回一个字符串,表示对包含目标控件的ID和事件参数的回发函数的JavaScript调用
string_jsSingle=ClientScript.GetPostBackClientHyperlink(_singleClickButton,"");
//给每一个可编辑的单元格增加事件
for(intcolumnIndex=_firstEditCellIndex;columnIndex<e.Row.Cells.Count;columnIndex++)
{
//增加列索引作为事件参数
stringjs=_jsSingle.Insert(_jsSingle.Length-2,columnIndex.ToString());
//给单元格增加onclick事件
e.Row.Cells[columnIndex].Attributes["onclick"]=js;
//给单元格增加鼠标经过时指针样式
e.Row.Cells[columnIndex].Attributes["style"]+="cursor:pointer;cursor:hand;";
}
}
}
在RowCommand事件内读出命令参数和事件参数。这会告诉我们被选中的行和列的索引。
int_rowIndex=int.Parse(e.CommandArgument.ToString());
int_columnIndex=int.Parse(Request.Form["__EVENTARGUMENT"]);
因为知道了被选中的行和列的索引,所以可以通过把显示控件的Visible设置为false,编辑控件的Visible设置为true来把某个独立的单元格设置为编辑模式。然后通过清除单元格的属性来删除被选中单元格的单击事件。
//获得被选中单元格的显示控件并设置其不可见
Control_displayControl=_gridView.Rows[_rowIndex].Cells[_columnIndex].Controls[1];
_displayControl.Visible=false;
//获得被选中单元格的编辑控件并设置其可见
Control_editControl=_gridView.Rows[_rowIndex].Cells[_columnIndex].Controls[3];
_editControl.Visible=true;
//清除被选中单元格属性以删除click事件
_gridView.Rows[_rowIndex].Cells[_columnIndex].Attributes.Clear();
下面有一些代码用于回发服务器后设置焦点到编辑控件,如果编辑控件是DropDownList的话,那么它的SelectedValue要设置为显示控件的值,如果编辑控件是TextBox的话,那么为了做好编辑的准备就要使它的文本被选中。
//设置焦点到被选中的编辑控件
ClientScript.RegisterStartupScript(GetType(),"SetFocus",
"<script>document.getElementById('"+_editControl.ClientID+"').focus();</script>");
//如果编辑控件是DropDownList的话
//SelectedValue设置为显示控件的值
if(_editControlisDropDownList&&_displayControlisLabel)
{
((DropDownList)_editControl).SelectedValue=((Label)_displayControl).Text;
}
//如果编辑控件是TextBox的话则选中文本框内文本
if(_editControlisTextBox)
{
((TextBox)_editControl).Attributes.Add("onfocus","this.select()");
}
在这个Demo中,我把事件被触发的历史记录也写到了页里。
如果GridView处于编辑模式的话,那么要在RowUpdating事件里去查找被选中行的每一个单元格。如果发现单元格处于编辑模式的话,那么就调用“更新”代码。在这个Demo中,数据保存在DataTable里,而这个DataTable则储存在session中。
//循环每一列以找到处于编辑模式下的单元格
for(inti=1;i<_gridView.Columns.Count;i++)
{
//获得单元格的编辑控件
Control_editControl=_gridView.Rows[e.RowIndex].Cells[i].Controls[3];
if(_editControl.Visible)
{
.updatethedata
}
}
为了确保RowUpdating事件在编辑单元格后被激发,要在Page_Load中来触发这个事件。编辑了TextBox后,通过按回车键或者单击另一单元格来使页面做回发处理,下面的这段代码就是用于确保任何数据的改变都会被更新。
if(this.GridView1.SelectedIndex>-1)
{
this.GridView1.UpdateRow(this.GridView1.SelectedIndex,false);
}
为了验证而注册回发和回调数据
在RowDataBound中创建的自定义事件必须要在页中注册。通过重写Render方法来调用ClientScriptManager.RegisterForEventValidation。通过GridViewRow.UniqueID返回行的唯一ID,按纽的唯一ID通过在行的唯一ID后附加“$ct100”而生成。
protectedoverridevoidRender(HtmlTextWriterwriter)
{
foreach(GridViewRowrinGridView1.Rows)
{
if(r.RowType==DataControlRowType.DataRow)
{
for(intcolumnIndex=_firstEditCellIndex;columnIndex<r.Cells.Count;columnIndex++)
{
Page.ClientScript.RegisterForEventValidation(r.UniqueID+"$ctl00",columnIndex.ToString());
}
}
}
base.Render(writer);
}
这将防止任何“回发或回调参数无效”的错误。
这个Demo中的其它示例
使用SQL数据源控件编辑某一独立的GridView单元格
用SqlDataSouce控件实现这个技术需要对GridView的RowUpdating事件做一些修改。当更新GridView的行的时候,SqlDataSource控件一般要把值(values)从EditItemTemplate转移到NewValues集合里。因为我们没有使用EditItemTemplate,所以这种情况下值(values)不会自动地转移到NewValues集合里。
e.NewValues.Add(key,value);
我在App_Data文件夹下使用了一个简单的SQLServerExpress数据库。(要使用你自己的数据库的话,你可以修改web.config里的连接字符串)
使用对象数据源控件编辑某一独立的GridView单元格
本示例使用了App_Code文件夹内的两个类:
·Task.cs–任务对象
·TaskDataAccess.cs–管理任务对象
Aspx页的后置代码与SQLDataSource示例是一样的。ObjectDataSource通过TaskDataAccess.cs类里的GetTasks和UpdateTask方法来管理数据。
有着电子数据表样式的GridView
这里有一个与电子数据表的样式很像的GridView。(虽然它看起来像一个电子数据表,但是并不是真的有像电子数据表一样的功能,它仍然是一个GridView。)
这里虽然有一些单击后改变单元格样式的附加代码,但是主要的代码还是与上面所述是相同的。
用SQL数据源控件实现有着电子数据表样式的GridView
本示例与上面的基本相同,但是它修改了GridView的RowUpdating事件以使其允许用SqlDataSource控件来工作。
参考
·
GridView和DataList响应单击数据行和双击数据行事件
·
ASP.NET2.0数据教程结论
如果你想在GridView中一次只针对一个单元格进行编辑,那么这个方法将会对你有所帮助。
译者注:事件验证(EventValidation)。出于安全目的,此功能验证回发或回调事件的参数是否来源于最初呈现这些事件的服务器控件。如果数据有效并且是预期的,则使用ClientScriptManager.RegisterForEventValidation方法来注册回发或回调数据以进行验证。
点击下载此文件
相关推荐
任意改变GridView某一行颜色和任意单元格颜色的源代码
编辑GridView单元格 说明:单元格获取焦点,则单元格处于编辑状态,单元格失去焦点,则立即更新数据库。采用非Ajax技术。 1、访问Session中的数据 这个例子是用户使用Session中数据。鼠标点击编辑GridView单元格。...
实现嵌套中的gridview单元格修改 datalist嵌套gridview,
GridView突出显示某一单元格(例如金额低于多少,分数不及格等
DevExpress设置单元格不可编辑,选单元格则选中一行,目的是只展示数据,不提供修改功能: DevexpressGridControl禁止点击单元格修改 设置GridView.OptionsBehavior的Editable选项设为False。在这种情况下,整个Grid...
当编辑gridview时,可能你只想编辑指定的gridview单元格的某一个,这个demo可能对你有帮助(包含源码)
GridView合并表头单元格 GridView合并表头单元格 GridView合并表头单元格
wpf GridView 合并单元格 Demo 简单 适合新手 使用工具vs2017
GrivView中的单元格合并, 类似于HTML中的跨行或跨列合并单元格,使GridView更方便的展示数据
GridView和GridData 行单击弹出详细页面 双击编辑状态更新
GridView合并单元格,引合并单元格,实际上是合并数据结构.然后把处理后的数据绑定到GridView控件中.
可编辑更新独立单元格的GridView[文].pdf
使用gridview进行数据绑定后,有时需要实现一个单元格有多个超链接的情况,而且每一行的超链接个数不同内容也不同,且超链接的内容需要根据后台绑定的动态数据确定。本代码中的代码就是为了解决该问题而做的,在Demo...
gridview合并单元格,将具有相同内容的单元格合并。
DevExpress 编辑GridControl中合并单元格,要求版本号在15以上
GridView空间中的各种使用方法,包括GridView无代码分页排序 ...GridView突出显示某一单元格(例如金额低于多少,分数不及格等) GridView加入自动求和求平均值小计 GridView数据导入Excel/Excel数据读入GridView
鼠标停留在GridView某一行时,行的颜色改变
GridView突出显示某一单元格(例如金额低于多少,分数不及格等) GridView加入自动求和求平均值小计 GridView数据导入Excel/Excel数据读入GridView GridView 编辑时在行中加入日期选择(不可输入)